diff --git a/NEWS.md b/NEWS.md index ade5947627d89..10028b8f527f4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,9 @@ Language changes * The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either `1 .+ 2` (the current meaning) or `1. + 2` ([#19089]). + * In string and character literals, backslash `\` may no longer + precede unrecognized escape characters ([#22800]). + Breaking changes ---------------- diff --git a/base/markdown/render/html.jl b/base/markdown/render/html.jl index 6b9a9802b6c87..2c350c666680d 100644 --- a/base/markdown/render/html.jl +++ b/base/markdown/render/html.jl @@ -26,7 +26,7 @@ const _htmlescape_chars = Dict('<'=>"<", '>'=>">", '"'=>""", '&'=>"&", # ' '=>" ", ) -for ch in "'`!\$\%()=+{}[]" +for ch in "'`!\$%()=+{}[]" _htmlescape_chars[ch] = "&#$(Int(ch));" end diff --git a/base/sparse/spqr.jl b/base/sparse/spqr.jl index 9b4cb77e3cd88..24fd4cf6e2970 100644 --- a/base/sparse/spqr.jl +++ b/base/sparse/spqr.jl @@ -390,9 +390,9 @@ end (\)(F::QRSparse{T}, B::StridedVecOrMat{T}) where {T} = _ldiv_basic(F, B) """ - (\)(F::QRSparse, B::StridedVecOrMat) + (\\)(F::QRSparse, B::StridedVecOrMat) -Solve the least squares problem ``\min\|Ax - b\|^2`` or the linear system of equations +Solve the least squares problem ``\\min\\|Ax - b\\|^2`` or the linear system of equations ``Ax=b`` when `F` is the sparse QR factorization of ``A``. A basic solution is returned when the problem is underdetermined. @@ -404,7 +404,7 @@ julia> A = sparse([1,2,4], [1,1,1], ones(3), 4, 2) [2, 1] = 1.0 [4, 1] = 1.0 -julia> qrfact(A)\ones(4) +julia> qrfact(A)\\ones(4) 2-element Array{Float64,1}: 1.0 0.0 diff --git a/base/statistics.jl b/base/statistics.jl index ee15c981920c8..2ff26208fed69 100644 --- a/base/statistics.jl +++ b/base/statistics.jl @@ -361,7 +361,7 @@ cov(X::AbstractMatrix, vardim::Int=1; corrected::Bool=true) = Compute the covariance between the vectors `x` and `y`. If `corrected` is `true` (the default), computes ``\\frac{1}{n-1}\\sum_{i=1}^n (x_i-\\bar x) (y_i-\\bar y)^*`` where ``*`` denotes the complex conjugate and `n = length(x) = length(y)`. If `corrected` is -`false`, computes ``\frac{1}{n}\sum_{i=1}^n (x_i-\\bar x) (y_i-\\bar y)^*``. +`false`, computes ``\\frac{1}{n}\\sum_{i=1}^n (x_i-\\bar x) (y_i-\\bar y)^*``. """ cov(x::AbstractVector, y::AbstractVector; corrected::Bool=true) = covm(x, Base.mean(x), y, Base.mean(y); corrected=corrected) diff --git a/src/flisp/read.c b/src/flisp/read.c index 6eec757a84294..2b57688cd86be 100644 --- a/src/flisp/read.c +++ b/src/flisp/read.c @@ -516,7 +516,12 @@ static value_t read_string(fl_context_t *fl_ctx) i += u8_wc_toutf8(&buf[i], wc); } else { - buf[i++] = read_escape_control_char((char)c); + char esc = read_escape_control_char((char)c); + if (esc == (char)c && !strchr("\\'\"$`", esc)) { + free(buf); + lerror(fl_ctx, fl_ctx->ParseError, "read: invalid escape sequence"); + } + buf[i++] = esc; } } else { diff --git a/test/libdl.jl b/test/libdl.jl index d283bc15cac18..b2ab2482b9be7 100644 --- a/test/libdl.jl +++ b/test/libdl.jl @@ -13,7 +13,7 @@ if !Sys.iswindows() || Sys.windows_version() >= Sys.WINDOWS_VISTA_VER end end @test length(filter(dlls) do dl - return ismatch(Regex("^libjulia(?:.*)\.$(Libdl.dlext)(?:\..+)?\$"), basename(dl)) + return ismatch(Regex("^libjulia(?:.*).$(Libdl.dlext)(?:..+)?\$"), basename(dl)) end) == 1 # look for something libjulia-like (but only one) # library handle pointer must not be NULL diff --git a/test/strings/basic.jl b/test/strings/basic.jl index 2e45013ab1b3f..72b6db05294ce 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -491,3 +491,7 @@ Base.endof(x::CharStr) = endof(x.chars) @test 'a' * 'b' == "ab" @test 'a' * "b" * 'c' == "abc" @test "a" * 'b' * 'c' == "abc" + +# unrecognized escapes in string/char literals +@test_throws ParseError parse("\"\\.\"") +@test_throws ParseError parse("\'\\.\'") diff --git a/test/strings/io.jl b/test/strings/io.jl index 061c744ae4192..9b85bead6098c 100644 --- a/test/strings/io.jl +++ b/test/strings/io.jl @@ -82,10 +82,6 @@ for i = 0:0x7f, p = ["","\0","x","xxx","\x7f","\uFF","\uFFF", @test string(unescape_string(string("\\x",hex(i,3),p))) == hp end -@test "\z" == unescape_string("\z") == "z" -@test "\X" == unescape_string("\X") == "X" -@test "\AbC" == unescape_string("\AbC") == "AbC" - @test "\0" == unescape_string("\\0") @test "\1" == unescape_string("\\1") @test "\7" == unescape_string("\\7")