From 889de01b24ae619107183f072cbe136998570dae Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Thu, 12 Mar 2020 15:02:40 -0700 Subject: [PATCH 01/12] Fix MacOS Notarization (#35080) We need to individually sign each Mach-O file independently, otherwise notarization bails. Note that you must sign the overall `.app` after each individual file is signed. I've also added more Entitlements. I've gone for a "gentle shotgun" approach, turning on everything that I think we could reasonably want. I wait expectantly for someone to complain that they need Location access turned on for some package. ;) (cherry picked from commit 418f1114a4a97524849bc3cb3077306a0b27691b) --- contrib/mac/app/Entitlements.plist | 14 ++++++++++++++ contrib/mac/app/Makefile | 9 +++++++-- contrib/mac/app/notarize_check.sh | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/contrib/mac/app/Entitlements.plist b/contrib/mac/app/Entitlements.plist index 49ad0bb0904a06..2e0912b4c0bf40 100644 --- a/contrib/mac/app/Entitlements.plist +++ b/contrib/mac/app/Entitlements.plist @@ -4,5 +4,19 @@ com.apple.security.automation.apple-events + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.debugger + + com.apple.security.cs.disable-library-validation + + com.apple.security.device.audio-input + + com.apple.security.device.camera + diff --git a/contrib/mac/app/Makefile b/contrib/mac/app/Makefile index 7f70cb38a001eb..665b4f1566b6f4 100644 --- a/contrib/mac/app/Makefile +++ b/contrib/mac/app/Makefile @@ -51,7 +51,12 @@ dmg/$(APP_NAME): startup.applescript julia.icns tar zxf $(JULIAHOME)/$(JULIA_BINARYDIST_FILENAME).tar.gz -C $@/Contents/Resources/julia --strip-components 1 if [ -n "$$MACOS_CODESIGN_IDENTITY" ]; then \ echo "Codesigning with identity $$MACOS_CODESIGN_IDENTITY"; \ - codesign -s "$$MACOS_CODESIGN_IDENTITY" --option=runtime --entitlements Entitlements.plist -v --deep $@; \ + MACHO_FILES=$$(find "$@" -type f -perm -755 | cut -d: -f1); \ + for f in $${MACHO_FILES}; do \ + echo "Codesigning $${f}..."; \ + codesign -s "$$MACOS_CODESIGN_IDENTITY" --option=runtime --entitlements Entitlements.plist -vvv --timestamp --deep --force "$${f}"; \ + done; \ + codesign -s "$$MACOS_CODESIGN_IDENTITY" --option=runtime --entitlements Entitlements.plist -vvv --timestamp --deep --force "$@"; \ else \ true; \ fi @@ -62,7 +67,7 @@ ifneq ($(filter root,$(ROOTFILES)),) @echo "We have to use sudo here to clean out folders owned by root. You may be asked for your password" sudo rm -rf dmg *.dmg notarize-*.xml else - rm -rf dmg *.dmg + rm -rf dmg *.dmg notarize-*.xml endif notarize-upload-$(DMG_NAME).xml: $(DMG_NAME) diff --git a/contrib/mac/app/notarize_check.sh b/contrib/mac/app/notarize_check.sh index e3f2e13f698eca..ccb46844abec3c 100755 --- a/contrib/mac/app/notarize_check.sh +++ b/contrib/mac/app/notarize_check.sh @@ -33,6 +33,10 @@ function wait_until_completed() echo -n "." sleep 10 continue + elif [[ ${STATUS} == "invalid" ]]; then + echo "invalid! Looks like something got borked:" + /usr/libexec/PlistBuddy -c "print notarization-info:LogFileURL" "${PLIST_FILE}" 2>/dev/null + exit 1 else echo "Notarization failed with status ${STATUS}" exit 1 From d04036f479064219c485cc8ed9fb5fff364a7cf9 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 9 Apr 2020 21:36:28 -0400 Subject: [PATCH 02/12] precompile: avoid a potential crash when adding methods (#35378) fixes #29859 (cherry picked from commit 8a55a27ea7f99be30bf17fc2c5e810cab4ded635) --- src/gf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gf.c b/src/gf.c index 5dc9fc71e7d179..94b1d4f6e00ef5 100644 --- a/src/gf.c +++ b/src/gf.c @@ -1266,7 +1266,8 @@ static int check_ambiguous_visitor(jl_typemap_entry_t *oldentry, struct typemap_ // ok: record that this method definition is being partially replaced // (either with a real definition, or an ambiguity error) - if (shadowed) { + // be careful not to try to scan something from the current dump-reload though + if (shadowed && oldentry->min_world != closure->newentry->min_world) { if (closure->shadowed == NULL) { closure->shadowed = (jl_value_t*)oldentry; } From fe434067f08c056483085aac6ac5aef31a2f8606 Mon Sep 17 00:00:00 2001 From: Shan Sikdar Date: Fri, 10 Apr 2020 10:54:26 -0400 Subject: [PATCH 03/12] add some checks for invalid expressions (#35363) add null check for module-default-defs, fix #34544 fix #35367 as well change jl_eval_module_expr to check 3rd arg is block (cherry picked from commit 8057c6035479fa29f52da4fa10335cc1ab90a805) --- src/ast.c | 2 +- src/jlfrontend.scm | 2 +- src/toplevel.c | 5 +++++ test/syntax.jl | 11 +++++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ast.c b/src/ast.c index 717e25e1a550ee..8826651befdd5f 100644 --- a/src/ast.c +++ b/src/ast.c @@ -549,7 +549,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m assert(jl_is_symbol(ex)); temp = jl_module_globalref(jl_core_module, (jl_sym_t*)ex); } - else if (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e))))) { + else if (iscons(e) && (sym == inert_sym || (sym == quote_sym && (!iscons(car_(e)))))) { ex = scm_to_julia_(fl_ctx, car_(e), mod); temp = jl_new_struct(jl_quotenode_type, ex); } diff --git a/src/jlfrontend.scm b/src/jlfrontend.scm index 994ee150bfe5bb..56e3932fd49ef6 100644 --- a/src/jlfrontend.scm +++ b/src/jlfrontend.scm @@ -149,7 +149,7 @@ (jl-expand-to-thunk (let* ((name (caddr e)) (body (cadddr e)) - (loc (cadr body)) + (loc (if (null? (cdr body)) () (cadr body))) (loc (if (and (pair? loc) (eq? (car loc) 'line)) (list loc) '())) diff --git a/src/toplevel.c b/src/toplevel.c index b4ccf1bfb80a49..3e101416e4e3ce 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -116,6 +116,11 @@ jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex) if (jl_array_len(ex->args) != 3 || !jl_is_expr(jl_exprarg(ex, 2))) { jl_error("syntax: malformed module expression"); } + + if (((jl_expr_t *)(jl_exprarg(ex, 2)))->head != jl_symbol("block")) { + jl_error("syntax: module expression third argument must be a block"); + } + int std_imports = (jl_exprarg(ex, 0) == jl_true); jl_sym_t *name = (jl_sym_t*)jl_exprarg(ex, 1); if (!jl_is_symbol(name)) { diff --git a/test/syntax.jl b/test/syntax.jl index 6fc8b4eb307b63..aa10517a155556 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -1985,6 +1985,17 @@ h35201(x; k=1) = (x, k) f35201(c) = h35201((;c...), k=true) @test f35201(Dict(:a=>1,:b=>3)) === ((a=1,b=3), true) + +@testset "issue #34544/35367" begin + # Test these evals shouldnt segfault + eval(Expr(:call, :eval, Expr(:quote, Expr(:module, true, :bar1, Expr(:block))))) + eval(Expr(:module, true, :bar2, Expr(:block))) + eval(Expr(:quote, Expr(:module, true, :bar3, Expr(:quote)))) + @test_throws ErrorException eval(Expr(:call, :eval, Expr(:quote, Expr(:module, true, :bar4, Expr(:quote))))) + @test_throws ErrorException eval(Expr(:module, true, :bar5, Expr(:foo))) + @test_throws ErrorException eval(Expr(:module, true, :bar6, Expr(:quote))) +end + # issue #35391 macro a35391(b) :(GC.@preserve ($(esc(b)),) ) From 3be9f109ac597854fb0cbd246f1fff545cae424a Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 22 Apr 2020 18:00:35 -0400 Subject: [PATCH 04/12] implement LibuvStream interface for BufferStream (#35545) It is noted as a non-OS stream, but has also been a subtype of LibuvStream since forever. #32309 did not add the `readerror` field. (cherry picked from commit de042102d7d607d19224600ca4a990cdf3cf67dc) --- base/stream.jl | 5 +++-- test/iobuffer.jl | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/base/stream.jl b/base/stream.jl index 7932f4fe69628c..059705ed4fa811 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -23,7 +23,6 @@ abstract type LibuvStream <: IO end # . +- Pipe # . +- Process (not exported) # . +- ProcessChain (not exported) -# +- BufferStream # +- DevNull (not exported) # +- Filesystem.File # +- LibuvStream (not exported) @@ -31,6 +30,7 @@ abstract type LibuvStream <: IO end # . +- TCPSocket # . +- TTY (not exported) # . +- UDPSocket +# . +- BufferStream (FIXME: 2.0) # +- IOBuffer = Base.GenericIOBuffer{Array{UInt8,1}} # +- IOStream @@ -1207,11 +1207,12 @@ end mutable struct BufferStream <: LibuvStream buffer::IOBuffer cond::Threads.Condition + readerror::Any is_open::Bool buffer_writes::Bool lock::ReentrantLock # advisory lock - BufferStream() = new(PipeBuffer(), Threads.Condition(), true, false, ReentrantLock()) + BufferStream() = new(PipeBuffer(), Threads.Condition(), nothing, true, false, ReentrantLock()) end isopen(s::BufferStream) = s.is_open diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 16680e76fb3261..d3c14a7503429a 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -254,6 +254,18 @@ end @test close(bstream) === nothing @test eof(bstream) @test bytesavailable(bstream) == 0 + flag = Ref{Bool}(false) + event = Base.Event() + bstream = Base.BufferStream() + task = @async begin + notify(event) + read(bstream, 16) + flag[] = true + end + wait(event) + write(bstream, rand(UInt8, 16)) + wait(task) + @test flag[] == true end @test flush(IOBuffer()) === nothing # should be a no-op From 75c7c600ced9cc7006b74eb3c55e1881d1bc2328 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Thu, 23 Apr 2020 23:19:18 -0700 Subject: [PATCH 05/12] Add a fast path for returning "" from repeat(str, 0) (#35579) Currently the case where `r == 0` falls through the same logic as every other non-negative value of `r` (aside from 1). This works for signed integers. However, this does not work for unsigned integers: in the loop where we unsafely fill in the output string, we're looping from 0 to `r - 1`, which for unsigned integers wraps around and causes us to request the address of the output string at a location that is well beyond what was allocated. Fixes #35578. (cherry picked from commit 1dcb42f29caffc98ad0722577844ce5c54c5ba0c) --- base/strings/substring.jl | 1 + test/strings/basic.jl | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/base/strings/substring.jl b/base/strings/substring.jl index cfebe9991eb7fb..d98dab5ae790b8 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -198,6 +198,7 @@ end function repeat(s::Union{String, SubString{String}}, r::Integer) r < 0 && throw(ArgumentError("can't repeat a string $r times")) + r == 0 && return "" r == 1 && return String(s) n = sizeof(s) out = _string_n(n*r) diff --git a/test/strings/basic.jl b/test/strings/basic.jl index d2be061b52d700..192592c215e917 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -620,15 +620,17 @@ end @test_throws ArgumentError repeat(c, -1) @test_throws ArgumentError repeat(s, -1) @test_throws ArgumentError repeat(S, -1) - @test repeat(c, 0) === "" - @test repeat(s, 0) === "" - @test repeat(S, 0) === "" - @test repeat(c, 1) === s - @test repeat(s, 1) === s - @test repeat(S, 1) === S - @test repeat(c, 3) === S - @test repeat(s, 3) === S - @test repeat(S, 3) === S*S*S + for T in (Int, UInt) + @test repeat(c, T(0)) === "" + @test repeat(s, T(0)) === "" + @test repeat(S, T(0)) === "" + @test repeat(c, T(1)) === s + @test repeat(s, T(1)) === s + @test repeat(S, T(1)) === S + @test repeat(c, T(3)) === S + @test repeat(s, T(3)) === S + @test repeat(S, T(3)) === S*S*S + end end # Issue #32160 (string allocation unsigned overflow) @test_throws OutOfMemoryError repeat('x', typemax(Csize_t)) From 9651235ad7dd325bdcc672d94694a221cabc3598 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 27 Apr 2020 13:47:56 -0400 Subject: [PATCH 06/12] exclude types with free variables from `type_morespecific` (#35555) (cherry picked from commit 0cedde636ed866364ad94ae0b4dd33918f447c40) --- src/subtype.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/subtype.c b/src/subtype.c index f251f7839f3093..00fbc5b54ac87d 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -3761,6 +3761,8 @@ JL_DLLEXPORT int jl_type_morespecific(jl_value_t *a, jl_value_t *b) { if (obviously_disjoint(a, b, 1)) return 0; + if (jl_has_free_typevars(a) || jl_has_free_typevars(b)) + return 0; if (jl_subtype(b, a)) return 0; if (jl_subtype(a, b)) From e76bf144f6977247b90aeab5e2bdbedb5f780f9e Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Tue, 28 Apr 2020 00:55:48 +0200 Subject: [PATCH 07/12] fix buggy rand(RandomDevice(), Bool) (#35590) (cherry picked from commit 0bab06f8a7f70d4518ad30e19a4c0a1968c875ad) --- stdlib/Random/src/RNGs.jl | 1 + stdlib/Random/test/runtests.jl | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/stdlib/Random/src/RNGs.jl b/stdlib/Random/src/RNGs.jl index 22271ba6109ba8..110fc367deb762 100644 --- a/stdlib/Random/src/RNGs.jl +++ b/stdlib/Random/src/RNGs.jl @@ -25,6 +25,7 @@ else # !windows end rand(rd::RandomDevice, sp::SamplerBoolBitInteger) = read(getfile(rd), sp[]) + rand(rd::RandomDevice, ::SamplerType{Bool}) = read(getfile(rd), UInt8) % Bool function getfile(rd::RandomDevice) devrandom = rd.unlimited ? DEV_URANDOM : DEV_RANDOM diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 49a5f5c0ccb3dc..20f81f73e344aa 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -455,6 +455,38 @@ for rng in [MersenneTwister(), RandomDevice()], end end +@testset "rand(Bool) uniform distribution" begin + for n in [rand(1:8), rand(9:16), rand(17:64)] + a = zeros(Bool, n) + as = zeros(Int, n) + # we will test statistical properties for each position of a, + # but also for 3 linear combinations of positions (for the array version) + lcs = unique!.([rand(1:n, 2), rand(1:n, 3), rand(1:n, 5)]) + aslcs = zeros(Int, 3) + for rng = (MersenneTwister(), RandomDevice()) + for scalar = [false, true] + fill!(a, 0) + fill!(as, 0) + fill!(aslcs, 0) + for _ = 1:49 + if scalar + for i in eachindex(as) + as[i] += rand(rng, Bool) + end + else + as .+= rand!(rng, a) + aslcs .+= [xor(getindex.(Ref(a), lcs[i])...) for i in 1:3] + end + end + @test all(x -> 7 <= x <= 42, as) # for each x, fails with proba ≈ 2/35_000_000 + if !scalar + @test all(x -> 7 <= x <= 42, aslcs) + end + end + end + end +end + # test reproducility of methods let mta = MersenneTwister(42), mtb = MersenneTwister(42) From 0203e947a4b13d7a6a92f5a849a2c7e506d9002d Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 3 May 2020 02:29:50 -0400 Subject: [PATCH 08/12] Fix dropped bytes when bulk reading from uv streams with oversized buffers (#35695) In readbytes!(s::UVStream, buf::AbstractVector{UInt8}, nb), we wrap `buf` in a PipeBuffer of maxsize nb and swap it in as the main buffer for the stream `s`. However, when we inform libuv of the size of the buffer, we instead use the size of the underlying array, which can be larger. In that case, we probably either drop bytes or override something that the user did not want overriden. (cherry picked from commit 3a84b51caf211159e402c2562962525c2b9249ea) --- base/stream.jl | 2 +- test/read.jl | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/base/stream.jl b/base/stream.jl index 059705ed4fa811..a2cd4d57106a7d 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -497,7 +497,7 @@ get(::TTY, key::Symbol, default) = key === :color ? have_color : default function alloc_request(buffer::IOBuffer, recommended_size::UInt) ensureroom(buffer, Int(recommended_size)) ptr = buffer.append ? buffer.size + 1 : buffer.ptr - nb = length(buffer.data) - ptr + 1 + nb = min(length(buffer.data), buffer.maxsize) - ptr + 1 return (pointer(buffer.data, ptr), nb) end diff --git a/test/read.jl b/test/read.jl index d7f1a4c11b01dd..6961dc29d2af66 100644 --- a/test/read.jl +++ b/test/read.jl @@ -596,3 +596,18 @@ end seekstart(io) @test_throws ErrorException read!(io, @view z[4:6]) end + +# Bulk read from pipe +let p = Pipe() + data = rand(UInt8, Base.SZ_UNBUFFERED_IO + 100) + Base.link_pipe!(p, reader_supports_async=true, writer_supports_async=true) + t = @async write(p.in, data) + @test read(p.out, UInt8) == data[1] + data_read = Vector{UInt8}(undef, 10*Base.SZ_UNBUFFERED_IO) + nread = readbytes!(p.out, data_read, Base.SZ_UNBUFFERED_IO + 50) + @test nread == Base.SZ_UNBUFFERED_IO + 50 + @test data_read[1:nread] == data[2:nread+1] + @test read(p.out, 49) == data[end-48:end] + wait(t) + close(p) +end From 36d26003543e015bfb10ed22af336bd98bd91d0d Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 5 May 2020 23:17:06 +0200 Subject: [PATCH 09/12] Fix and test PCRE error message getter. (#35728) (cherry picked from commit 9c2492eb87308348521a3833175f79e4bc015d9e) --- base/pcre.jl | 2 +- test/regex.jl | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/base/pcre.jl b/base/pcre.jl index b0d96b90dfab0f..4d27f7502aca2f 100644 --- a/base/pcre.jl +++ b/base/pcre.jl @@ -147,7 +147,7 @@ free_match_context(context) = function err_message(errno) buffer = Vector{UInt8}(undef, 256) ccall((:pcre2_get_error_message_8, PCRE_LIB), Cvoid, - (Int32, Ptr{UInt8}, Csize_t), errno, buffer, sizeof(buffer)) + (UInt32, Ptr{UInt8}, Csize_t), errno, buffer, sizeof(buffer)) GC.@preserve buffer unsafe_string(pointer(buffer)) end diff --git a/test/regex.jl b/test/regex.jl index 6a32a49051d139..294786f5690357 100644 --- a/test/regex.jl +++ b/test/regex.jl @@ -139,4 +139,7 @@ # Test that PCRE throws the correct kind of error # TODO: Uncomment this once the corresponding change has propagated to CI #@test_throws ErrorException Base.PCRE.info(C_NULL, Base.PCRE.INFO_NAMECOUNT, UInt32) + + # test that we can get the error message of negative error codes + @test Base.PCRE.err_message(Base.PCRE.ERROR_NOMEMORY) isa String end From 8b3a4a2df52e3bc53d6fc6c74c88287e906dd4ad Mon Sep 17 00:00:00 2001 From: Shan Sikdar Date: Fri, 8 May 2020 15:08:34 -0400 Subject: [PATCH 10/12] Have matrix square root account for Rii=Rjj=0 to prevent NaN values (#35758) (cherry picked from commit 880c73199b5d304912b18b3e4f82f95b37c19e6f) --- stdlib/LinearAlgebra/src/triangular.jl | 4 +++- stdlib/LinearAlgebra/test/triangular.jl | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/stdlib/LinearAlgebra/src/triangular.jl b/stdlib/LinearAlgebra/src/triangular.jl index 2b6698ecf3840c..4d4aa5a514d00e 100644 --- a/stdlib/LinearAlgebra/src/triangular.jl +++ b/stdlib/LinearAlgebra/src/triangular.jl @@ -2566,7 +2566,9 @@ function sqrt(A::UpperTriangular{T},::Val{realmatrix}) where {T,realmatrix} @simd for k = i+1:j-1 r -= R[i,k]*R[k,j] end - iszero(r) || (R[i,j] = sylvester(R[i,i],R[j,j],-r)) + if !(iszero(r) || (iszero(R[i,i]) && iszero(R[j,j]))) + R[i,j] = sylvester(R[i,i],R[j,j],-r) + end end end return UpperTriangular(R) diff --git a/stdlib/LinearAlgebra/test/triangular.jl b/stdlib/LinearAlgebra/test/triangular.jl index 5f6ec8771a0301..47d08e9b56c35a 100644 --- a/stdlib/LinearAlgebra/test/triangular.jl +++ b/stdlib/LinearAlgebra/test/triangular.jl @@ -611,4 +611,10 @@ end end end +# Issue 35058 +let A = [0.9999999999999998 4.649058915617843e-16 -1.3149405273715513e-16 9.9959579317056e-17; -8.326672684688674e-16 1.0000000000000004 2.9280733590254494e-16 -2.9993900031619594e-16; 9.43689570931383e-16 -1.339206523454095e-15 1.0000000000000007 -8.550505126287743e-16; -6.245004513516506e-16 -2.0122792321330962e-16 1.183061278035052e-16 1.0000000000000002], + B = [0.09648289218436859 0.023497875751503007 0.0 0.0; 0.023497875751503007 0.045787575150300804 0.0 0.0; 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0] + @test sqrt(A*B*A')^2 ≈ A*B*A' +end + end # module TestTriangular From c9b9b8c2167e7f0c5de9dc51ee92414c37187608 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Sat, 18 Apr 2020 16:18:47 -0400 Subject: [PATCH 11/12] fix #35134, regression in printing nested quote Exprs (#35479) (cherry picked from commit e00db7b3e5656a58116bb89f8eb83499f0c9b763) --- base/show.jl | 34 +++++------- doc/src/manual/metaprogramming.md | 16 +++--- test/show.jl | 91 ++++--------------------------- 3 files changed, 35 insertions(+), 106 deletions(-) diff --git a/base/show.jl b/base/show.jl index 1c6e5f4cf0b101..8dc9e93a7919fe 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1207,13 +1207,7 @@ function show_unquoted_expr_fallback(io::IO, ex::Expr, indent::Int, quote_level: show(io, ex.head) for arg in ex.args print(io, ", ") - if isa(arg, Expr) - print(io, ":(") - show_unquoted(io, arg, indent, 0, quote_level+1) - print(io, ")") - else - show(io, arg) - end + show(io, arg) end print(io, "))") end @@ -1603,17 +1597,19 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In elseif head === :quote && nargs == 1 && isa(args[1], Symbol) show_unquoted_quote_expr(IOContext(io, beginsym=>false), args[1]::Symbol, indent, 0, quote_level+1) - elseif head === :quote && nargs == 1 && is_expr(args[1], :block) - show_block(IOContext(io, beginsym=>false), "quote", Expr(:quote, args[1].args...), indent, - quote_level+1) - print(io, "end") - elseif head === :quote && nargs == 1 - print(io, ":(") - show_unquoted(IOContext(io, beginsym=>false), args[1], indent+2, 0, quote_level+1) - print(io, ")") - elseif head === :quote - show_block(IOContext(io, beginsym=>false), "quote", ex, indent, quote_level+1) - print(io, "end") + elseif head === :quote && !get(io, :unquote_fallback, true) + if nargs == 1 && is_expr(args[1], :block) + show_block(IOContext(io, beginsym=>false), "quote", Expr(:quote, args[1].args...), indent, + quote_level+1) + print(io, "end") + elseif nargs == 1 + print(io, ":(") + show_unquoted(IOContext(io, beginsym=>false), args[1], indent+2, 0, quote_level+1) + print(io, ")") + else + show_block(IOContext(io, beginsym=>false), "quote", ex, indent, quote_level+1) + print(io, "end") + end elseif head === :gotoifnot && nargs == 2 && isa(args[2], Int) print(io, "unless ") @@ -1648,7 +1644,7 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In if head === :$ quote_level -= 1 end - if head === :$ && quote_level < 0 && get(io, :unquote_fallback, true) + if head === :$ && get(io, :unquote_fallback, true) unhandled = true else print(io, head) diff --git a/doc/src/manual/metaprogramming.md b/doc/src/manual/metaprogramming.md index b16d9677f2e27c..1ce4885d495d0e 100644 --- a/doc/src/manual/metaprogramming.md +++ b/doc/src/manual/metaprogramming.md @@ -261,10 +261,10 @@ julia> x = :(1 + 2); julia> e = quote quote $x end end quote #= none:1 =# - quote - #= none:1 =# - $x - end + $(Expr(:quote, quote + #= none:1 =# + $(Expr(:$, :x)) +end)) end ``` @@ -289,10 +289,10 @@ This is done with multiple `$`s: julia> e = quote quote $$x end end quote #= none:1 =# - quote - #= none:1 =# - $(1 + 2) - end + $(Expr(:quote, quote + #= none:1 =# + $(Expr(:$, :(1 + 2))) +end)) end ``` diff --git a/test/show.jl b/test/show.jl index b630c696582603..db277729c2f9b3 100644 --- a/test/show.jl +++ b/test/show.jl @@ -888,8 +888,8 @@ test_mt(show_f5, "show_f5(A::AbstractArray{T,N}, indices::Vararg{$Int,N})") @test_repr repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) @test_repr "Expr(:quote, Expr(:typed_vcat, Expr(:\$, :a), 1))" @test_repr "Expr(:quote, Expr(:typed_hcat, Expr(:\$, :a), 1))" -@test repr(Expr(:quote, Expr(:typed_vcat, Expr(:$, :a), 1))) == ":(:(\$a[1;]))" -@test repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) == ":(:(\$a[1]))" +@test_repr repr(Expr(:quote, Expr(:typed_vcat, Expr(:$, :a), 1))) +@test_repr repr(Expr(:quote, Expr(:typed_hcat, Expr(:$, :a), 1))) # Printing of :(function f end) @test sprint(show, :(function f end)) == ":(function f end)" @@ -911,63 +911,6 @@ end""" \$a + \$b end end""" -@test repr(Meta.parse( -"""macro m(a, b) - quote - \$a + \$b - end -end""")) == -""" -:(macro m(a, b) - #= none:2 =# - quote - #= none:3 =# - \$a + \$b - end - end)""" -@test repr(Base.remove_linenums!(Meta.parse( -"""macro m(a, b) - quote - \$a + \$b - end -end"""))) == -""" -:(macro m(a, b) - quote - \$a + \$b - end - end)""" -@test repr(Meta.parse( -"""macro m(a, b) - :(\$a + \$b) -end""")) == -":(macro m(a, b)\n #= none:2 =#\n :(\$a + \$b)\n end)" -@test repr(Expr(:macro, Expr(:call, :m, :x), Expr(:quote, Expr(:call, :+, Expr(:($), :x), 1)))) == -":(macro m(x)\n :(\$x + 1)\n end)" - -# nested quotes and interpolations -@test repr(Meta.parse( -"""quote - quote - \$\$x - end -end""")) == -""" -:(quote - #= none:2 =# - quote - #= none:3 =# - \$\$x - end - end)""" -@weak_test_repr """ -quote - #= none:2 =# - quote - #= none:3 =# - \$\$x - end -end""" # fallback printing + nested quotes and unquotes @weak_test_repr repr(Expr(:block, LineNumberNode(0, :none), @@ -980,26 +923,15 @@ end""" @test_repr "Expr(:exotic_head, Expr(:call, :+, 1, \$\$y))" @test_repr ":(Expr(:exotic_head, Expr(:call, :+, 1, \$y)))" @test_repr ":(:(Expr(:exotic_head, Expr(:call, :+, 1, \$\$y))))" -@test repr(Expr(:block, LineNumberNode(0, :none), - Expr(:exotic_head, Expr(:$, :x)))) == -""" -quote - #= none:0 =# - \$(Expr(:exotic_head, :(\$x))) -end""" @test repr(Expr(:exotic_head, Expr(:call, :+, 1, :(Expr(:$, :y))))) == ":(\$(Expr(:exotic_head, :(1 + Expr(:\$, :y)))))" -@test repr(Expr(:exotic_head, Expr(:call, :+, 1, Expr(:quote, Expr(:$, :y))))) == - ":(\$(Expr(:exotic_head, :(1 + :(\$y)))))" -@test repr(Expr(:quote, Expr(:exotic_head, Expr(:call, :+, 1, Expr(:$, :y))))) == - ":(:(\$(Expr(:exotic_head, :(1 + \$y)))))" @test repr(Expr(:block, Expr(:(=), :y, 2), Expr(:quote, Expr(:exotic_head, Expr(:call, :+, 1, Expr(:$, :y)))))) == """ quote y = 2 - :(\$(Expr(:exotic_head, :(1 + \$y)))) + \$(Expr(:quote, :(\$(Expr(:exotic_head, :(1 + \$(Expr(:\$, :y)))))))) end""" @test repr(eval(Expr(:block, Expr(:(=), :y, 2), Expr(:quote, Expr(:exotic_head, @@ -1009,20 +941,20 @@ end""" # nested quotes and blocks @test_repr "Expr(:quote, Expr(:block, :a, :b))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :a, LineNumberNode(0, :none), :b))) -@test repr(Expr(:quote, Expr(:block, :a, :b))) == +@test_broken repr(Expr(:quote, Expr(:block, :a, :b))) == ":(quote a b end)" @test_repr "Expr(:quote, Expr(:block, :a))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :a))) -@test repr(Expr(:quote, Expr(:block, :a))) == +@test_broken repr(Expr(:quote, Expr(:block, :a))) == ":(quote a end)" @test_repr "Expr(:quote, Expr(:block, :(a + b)))" @weak_test_repr repr(Expr(:quote, Expr(:block, LineNumberNode(0, :none), :(a + b)))) -@test repr(Expr(:quote, Expr(:block, :(a + b)))) == +@test_broken repr(Expr(:quote, Expr(:block, :(a + b)))) == ":(quote a + b end)" @@ -1033,8 +965,9 @@ end""" @test_repr ":(QuoteNode(\$x))" @test_repr ":(:(QuoteNode(\$\$x)))" @test repr(QuoteNode(Expr(:$, :x))) == ":(\$(QuoteNode(:(\$(Expr(:\$, :x))))))" -@test repr(QuoteNode(Expr(:quote, Expr(:$, :x)))) == ":(\$(QuoteNode(:(:(\$x)))))" -@test repr(Expr(:quote, QuoteNode(Expr(:$, :x)))) == ":(:(\$(QuoteNode(:(\$(Expr(:\$, :x)))))))" +@test repr(QuoteNode(Expr(:quote, Expr(:$, :x)))) == ":(\$(QuoteNode(:(\$(Expr(:quote, :(\$(Expr(:\$, :x)))))))))" +@test repr(Expr(:quote, QuoteNode(Expr(:$, :x)))) == ":(\$(Expr(:quote, :(\$(QuoteNode(:(\$(Expr(:\$, :x)))))))))" +@test repr(Expr(:quote, Expr(:quote, Expr(:foo)))) == ":(\$(Expr(:quote, :(\$(Expr(:quote, :(\$(Expr(:foo)))))))))" # unquoting @test_repr "\$y" @@ -1057,13 +990,13 @@ y856739 = 2 x856739 = :y856739 z856739 = [:a, :b] @test_repr repr(:(:(f($$x856739)))) -@test repr(:(:(f($$x856739)))) == ":(:(f(\$y856739)))" +@test_broken repr(:(:(f($$x856739)))) == ":(:(f(\$y856739)))" @test repr(eval(:(:(f($$x856739))))) == ":(f(2))" @test_repr repr(:(:(f($x856739)))) -@test repr(:(:(f($x856739)))) == ":(:(f(\$x856739)))" +@test_broken repr(:(:(f($x856739)))) == ":(:(f(\$x856739)))" @test repr(eval(:(:(f($x856739))))) == ":(f(y856739))" @test_repr repr(:(:(f($(($z856739)...))))) -@test repr(:(:(f($(($z856739)...))))) == ":(:(f(\$([:a, :b]...))))" +@test_broken repr(:(:(f($(($z856739)...))))) == ":(:(f(\$([:a, :b]...))))" @test repr(eval(:(:(f($(($z856739)...)))))) == ":(f(a, b))" # string interpolation, if this is what the comment in test_rep function From c0b1a0caac4a5dc52425d0d63e91aca96a2d971e Mon Sep 17 00:00:00 2001 From: Kristoffer Date: Sun, 10 May 2020 13:24:34 +0200 Subject: [PATCH 12/12] bump Pkg version to latest release.1.4 --- .../Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/md5 | 1 + .../sha512 | 1 + .../Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/md5 | 1 - .../sha512 | 1 - stdlib/Pkg.version | 4 ++-- 5 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/md5 create mode 100644 deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/sha512 delete mode 100644 deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/sha512 diff --git a/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/md5 b/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/md5 new file mode 100644 index 00000000000000..742d844df5bb24 --- /dev/null +++ b/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/md5 @@ -0,0 +1 @@ +c43b575438cdffd34c51ef6953d28337 diff --git a/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/sha512 b/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/sha512 new file mode 100644 index 00000000000000..e68e609a681680 --- /dev/null +++ b/deps/checksums/Pkg-38f72686c378a4c61d382fe3b081f3435942ac82.tar.gz/sha512 @@ -0,0 +1 @@ +91a72184a80c5856390cd2879ff29dad1583db7c1657c7b9d9b1d67b6c5c465319ee85052d358471d2de9d311da50989fa848cb47730e59da769a224286655da diff --git a/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/md5 b/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/md5 deleted file mode 100644 index 6a1f3e9c175280..00000000000000 --- a/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a107b2b69d899e5191e7cdbff263df10 diff --git a/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/sha512 b/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/sha512 deleted file mode 100644 index 0e6d8858a9675b..00000000000000 --- a/deps/checksums/Pkg-9419c70af69153cd5c4276bff90fbb135e0aa3f1.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -beab318b1cf96a2f0957f26d33f2d06e6dfabed405778f3945caf6372cc62ed74ff069e912475f3e553cf3013db73a2c73f2a758a3e3b1ba21db0471b7182dbe diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 3aa9e0e8baf925..47c1084ba7f11f 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,2 +1,2 @@ -PKG_BRANCH = master -PKG_SHA1 = 9419c70af69153cd5c4276bff90fbb135e0aa3f1 +PKG_BRANCH = release-1.4 +PKG_SHA1 = 38f72686c378a4c61d382fe3b081f3435942ac82