Commit 999c80ac by Iain Buclaw

libphobos: Backport library fixes from mainline

- core.cpuid has been fixed to not use i7 detection on AMD processors.
- std.net.curl has been fixed to correctly handle HTTP/2 status lines.
- std.zip has had a test fixed to not rely on unzip being installed.

libphobos/ChangeLog:

	PR d/95166
	* libdruntime/core/cpuid.d (cpuidX86): Do not use i7 detection on AMD
	processors.
	(hasCPUID): Fix deprecated asm syntax.

	PR d/95167
	* src/std/zip.d (unittest): Skip test if unzip is not installed.

	PR d/95168
	* src/std/net/curl.d (HTTP.onReceiveHeader): Move status line parsing
	to ...
	(HTTP.parseStatusLine): ... here.  New function.  Add support for
	parsing HTTP/2 status lines.
parent 79f2ae6e
2020-05-17 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/95166
* libdruntime/core/cpuid.d (cpuidX86): Do not use i7 detection on AMD
processors.
(hasCPUID): Fix deprecated asm syntax.
PR d/95167
* src/std/zip.d (unittest): Skip test if unzip is not installed.
PR d/95168
* src/std/net/curl.d (HTTP.onReceiveHeader): Move status line parsing
to ...
(HTTP.parseStatusLine): ... here. New function. Add support for
parsing HTTP/2 status lines.
2020-05-07 Release Manager 2020-05-07 Release Manager
* GCC 10.1.0 released. * GCC 10.1.0 released.
......
...@@ -941,13 +941,27 @@ void cpuidX86() ...@@ -941,13 +941,27 @@ void cpuidX86()
datacache[0].lineSize = 32; datacache[0].lineSize = 32;
} }
} }
if (max_cpuid >= 0x0B) { if (cf.probablyIntel && max_cpuid >= 0x0B) {
// For Intel i7 and later, use function 0x0B to determine // For Intel i7 and later, use function 0x0B to determine
// cores and hyperthreads. // cores and hyperthreads.
getCpuInfo0B(); getCpuInfo0B();
} else { } else {
if (hyperThreadingBit) cf.maxThreads = (apic>>>16) & 0xFF; if (hyperThreadingBit) cf.maxThreads = (apic>>>16) & 0xFF;
else cf.maxThreads = cf.maxCores; else cf.maxThreads = cf.maxCores;
if (cf.probablyAMD && max_extended_cpuid >= 0x8000_001E) {
version (GNU) asm pure nothrow @nogc {
"cpuid" : "=a" (a), "=b" (b) : "a" (0x8000_001E) : "ecx", "edx";
} else {
asm pure nothrow @nogc {
mov EAX, 0x8000_001e;
cpuid;
mov b, EBX;
}
}
ubyte coresPerComputeUnit = ((b >> 8) & 3) + 1;
cf.maxCores = cf.maxThreads / coresPerComputeUnit;
}
} }
} }
...@@ -975,7 +989,7 @@ bool hasCPUID() ...@@ -975,7 +989,7 @@ bool hasCPUID()
xor {(%%esp), %%eax|eax, [esp]} xor {(%%esp), %%eax|eax, [esp]}
# eax = whichever bits were changed # eax = whichever bits were changed
popf{l|d} # Restore original EFLAGS popf{l|d} # Restore original EFLAGS
" : "=a" flags; " : "=a" (flags);
} }
} }
else version (D_InlineAsm_X86) else version (D_InlineAsm_X86)
......
...@@ -2451,7 +2451,6 @@ struct HTTP ...@@ -2451,7 +2451,6 @@ struct HTTP
in char[] value) callback) in char[] value) callback)
{ {
import std.algorithm.searching : startsWith; import std.algorithm.searching : startsWith;
import std.conv : to;
import std.regex : regex, match; import std.regex : regex, match;
import std.uni : toLower; import std.uni : toLower;
...@@ -2471,18 +2470,8 @@ struct HTTP ...@@ -2471,18 +2470,8 @@ struct HTTP
if (header.startsWith("HTTP/")) if (header.startsWith("HTTP/"))
{ {
headersIn.clear(); headersIn.clear();
if (parseStatusLine(header, status))
const m = match(header, regex(r"^HTTP/(\d+)\.(\d+) (\d+) (.*)$"));
if (m.empty)
{ {
// Invalid status line
}
else
{
status.majorVersion = to!ushort(m.captures[1]);
status.minorVersion = to!ushort(m.captures[2]);
status.code = to!ushort(m.captures[3]);
status.reason = m.captures[4].idup;
if (onReceiveStatusLine != null) if (onReceiveStatusLine != null)
onReceiveStatusLine(status); onReceiveStatusLine(status);
} }
...@@ -2517,6 +2506,37 @@ struct HTTP ...@@ -2517,6 +2506,37 @@ struct HTTP
private RefCounted!Impl p; private RefCounted!Impl p;
/// Parse status line, as received from / generated by cURL.
private static bool parseStatusLine(in char[] header, out StatusLine status) @safe
{
import std.conv : to;
import std.regex : regex, match;
const m = match(header, regex(r"^HTTP/(\d+)(?:\.(\d+))? (\d+)(?: (.*))?$"));
if (m.empty)
return false; // Invalid status line
else
{
status.majorVersion = to!ushort(m.captures[1]);
status.minorVersion = m.captures[2].length ? to!ushort(m.captures[2]) : 0;
status.code = to!ushort(m.captures[3]);
status.reason = m.captures[4].idup;
return true;
}
}
@safe unittest
{
StatusLine status;
assert(parseStatusLine("HTTP/1.1 200 OK", status)
&& status == StatusLine(1, 1, 200, "OK"));
assert(parseStatusLine("HTTP/1.0 304 Not Modified", status)
&& status == StatusLine(1, 0, 304, "Not Modified"));
// The HTTP2 protocol is binary; cURL generates this fake text header.
assert(parseStatusLine("HTTP/2 200", status)
&& status == StatusLine(2, 0, 200, null));
}
/** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl) /** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl)
$(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25) $(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)
......
...@@ -970,6 +970,12 @@ version (Posix) @system unittest ...@@ -970,6 +970,12 @@ version (Posix) @system unittest
{ {
import std.datetime, std.file, std.format, std.path, std.process, std.stdio; import std.datetime, std.file, std.format, std.path, std.process, std.stdio;
if (executeShell("unzip").status != 0)
{
writeln("Can't run unzip, skipping unzip test");
return;
}
auto zr = new ZipArchive(); auto zr = new ZipArchive();
auto am = new ArchiveMember(); auto am = new ArchiveMember();
am.compressionMethod = CompressionMethod.deflate; am.compressionMethod = CompressionMethod.deflate;
......
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