]> granicus.if.org Git - graphviz/log
graphviz
2 years agographml2gv: remove unnecessary dynamic allocation of user data
Matthew Fernandez [Fri, 23 Dec 2022 21:27:01 +0000 (13:27 -0800)]
graphml2gv: remove unnecessary dynamic allocation of user data

2 years agodotgen make_flat_adj_edges: remove unnecessary dynamic allocation of 'attrs'
Matthew Fernandez [Fri, 23 Dec 2022 21:12:45 +0000 (13:12 -0800)]
dotgen make_flat_adj_edges: remove unnecessary dynamic allocation of 'attrs'

2 years agoMerge branch 'smattr/gitlab-1720' into 'main'
Matthew Fernandez [Sat, 24 Dec 2022 17:50:34 +0000 (17:50 +0000)]
Merge branch 'smattr/gitlab-1720' into 'main'

fix reading incorrect input in #1710 test case

See merge request graphviz/graphviz!3010

2 years agofix reading incorrect input in #1710 test case
Matthew Fernandez [Fri, 23 Dec 2022 04:16:56 +0000 (20:16 -0800)]
fix reading incorrect input in #1710 test case

A mistake in 632fe0bd1cfc6a4f636db4f85206aff6720bdc6b made this test read from
/dev/null instead of the input file it was supposed to read. Note that this
required some tweak to the skip condition. The Windows platforms on which this
fails seems all over the place and expressing the exact pattern seemed too
complex. For the curious, what we currently see in CI is:

  ┌──────────────┬─────────┬──────────────┬─────────┬────────┐
  │ architecture │ OS      │ build system │ mode    │ result │
  ╞══════════════╪═════════╪══════════════╪═════════╪════════╡
  │ x86          │ Windows │ MS Build     │ debug   │ FAIL   │
  │              │         │              ├─────────┼────────┤
  │              │         │              │ release │ pass   │
  │              │         ├──────────────┼─────────┼────────┤
  │              │         │ CMake        │ debug   │ FAIL   │
  │              │         │              ├─────────┼────────┤
  │              │         │              │ release │ FAIL   │
  │              ├─────────┼──────────────┼─────────┼────────┤
  │              │ MinGW   │ CMake        │ -       │ pass   │
  ├──────────────┼─────────┼──────────────┼─────────┼────────┤
  │ x86-64       │ Windows │ CMake        │ debug   │ FAIL   │
  │              │         │              ├─────────┼────────┤
  │              │         │              │ release │ FAIL   │
  │              ├─────────┼──────────────┼─────────┼────────┤
  │              │ MinGW   │ CMake        │ -       │ FAIL   │
  └──────────────┴─────────┴──────────────┴─────────┴────────┘

I would not be surprised if these results are not stable. It is likely this
failure presents across all platforms, but is dependent on things like Address
Space Layout Randomization to exhibit.

Gitlab: #1710, #1720

2 years agoMerge branch 'smattr/331f7848-cb40-4753-91cb-c1599c4e3000' into 'main'
Matthew Fernandez [Fri, 23 Dec 2022 20:20:37 +0000 (20:20 +0000)]
Merge branch 'smattr/331f7848-cb40-4753-91cb-c1599c4e3000' into 'main'

Start 7.0.6 development

See merge request graphviz/graphviz!3008

2 years agoStart 7.0.6 development
Matthew Fernandez [Fri, 23 Dec 2022 19:32:00 +0000 (11:32 -0800)]
Start 7.0.6 development

2 years agoMerge branch 'smattr/26ab1e3b-7718-4870-a101-5767137531c5' into 'main'
Matthew Fernandez [Fri, 23 Dec 2022 19:30:12 +0000 (19:30 +0000)]
Merge branch 'smattr/26ab1e3b-7718-4870-a101-5767137531c5' into 'main'

Stable Release 7.0.5

See merge request graphviz/graphviz!3001

2 years agoStable Release 7.0.5
Matthew Fernandez [Wed, 14 Dec 2022 16:05:32 +0000 (08:05 -0800)]
Stable Release 7.0.5

2 years agoMerge branch 'smattr/gitlab-2329' into 'main'
Matthew Fernandez [Wed, 21 Dec 2022 05:26:48 +0000 (05:26 +0000)]
Merge branch 'smattr/gitlab-2329' into 'main'

CI: disable Cygwin jobs

See merge request graphviz/graphviz!3004

2 years agoCI: disable Cygwin jobs
Matthew Fernandez [Wed, 21 Dec 2022 04:35:00 +0000 (20:35 -0800)]
CI: disable Cygwin jobs

These are currently erroring:

  $ wget https://cygwin.com/setup-x86_64.exe -OutFile C:\setup-x86_64.exe
  wget : <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  <html><head>
  <title>403 Forbidden</title>
  </head><body>
  <h1>Forbidden</h1>
  <p>You don't have permission to access this resource.</p>
  </body></html>
  At line:1 char:1
  + wget https://cygwin.com/setup-x86_64.exe -OutFile C:\setup-x86_64.exe
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
     eption
      + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Gitlab: #2329

2 years agoMerge branch 'smattr/agxbuf-sso' into 'main'
Matthew Fernandez [Wed, 21 Dec 2022 04:07:47 +0000 (04:07 +0000)]
Merge branch 'smattr/agxbuf-sso' into 'main'

cgraph: implement SSO on agxbuf

Closes #2302 and #2326

See merge request graphviz/graphviz!3003

2 years agocgraph agxbuf: make inline strings the default
Matthew Fernandez [Sat, 10 Sep 2022 21:32:15 +0000 (14:32 -0700)]
cgraph agxbuf: make inline strings the default

This change switches both `agxbinit` and zero-initialization (`agxbuf xb = {0}`)
to result in a buffer with inline storage. This means string data is written
inline until it becomes too large to store within the `agxbuf` struct itself,
when it is then relocated to the heap.

This is an optimization. Short dynamic strings can now be written completely
without heap allocation. For example, stringifying a number
(`agxbprint(&xb, "%d", i)`) will fit fully within the inline buffer.

Some performance evaluation comparing the merge-base of this series
(740c4bf1edba931be0698de7bfde629eba2f40c0) to the current commit follows. These
numbers were derived using `/usr/bin/time` and Valgrind on `-O3 -flto -DNDEBUG`
builds of Graphviz. Instruction counts are provided for examples that are not
too long running.

  ┌────────┬────────────────────────────┬────────────────────────────┬──────┐
  │        │ before                     │ after                      │ diff │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ chain¹ │ 1.16s                      │ 1.05s                      │  -9% │
  │        │ 10436971652 instructions   │ 9006483829 instructions    │ -14% │
  │        │ 444MB peak RSS             │ 180MB peak RSS             │ -59% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ long²  │ 2.69s                      │ 2.39s                      │ -11% │
  │        │ 22856315061 instructions   │ 19359309874 instructions   │ -15% │
  │        │ 1056MB peak RSS            │ 416MB peak RSS             │ -61% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 456a³  │ 4h16m36s                   │ 4h13m46s                   │  -1% │
  │        │ 881MB peak RSS             │ 861MB peak RSS             │  -2% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 456b⁴  │ 3h57m41s                   │ 3h59m32s                   │  +1% │
  │        │ 907MB peak RSS             │ 886MB peak RSS             │  -2% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 1652a⁵ │ 17.98s                     │ 17.81s                     │  -1% │
  │        │ 113257927412 instructions  │ 113083410200 instructions  │  -0% │
  │        │ 97MB peak RSS              │ 52MB peak RSS              │ -46% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 1652b⁶ │ 2m09s                      │ 2m08s                      │  -1% │
  │        │ 1697003634008 instructions │ 1696880318663 instructions │  -0% │
  │        │ 20MB peak RSS              │ 16MB peak RSS              │ -20% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 1718⁷  │ 2m34s                      │ 2m35s                      │  +1% │
  │        │ 1620909322870 instructions │ 1620889232022 instructions │  -0% │
  │        │ 20MB peak RSS              │ 18MB peak RSS              │ -10% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 1864a⁸ │ 32m05s                     │ 34m22s                     │  +7% │
  │        │ 3435MB peak RSS            │ 1479MB peak RSS            │ -57% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 1864b⁹ │ 14.68s                     │ 13.62s                     │  -7% │
  │        │ 89053964853 instructions   │ 83880586677 instructions   │  -6% │
  │        │ 2421MB peak RSS            │ 464MB peak RSS             │ -81% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 2064¹⁰ │ 11m37s                     │ 11m38s                     │  +0% │
  │        │ 815499533953 instructions  │ 814007887571 instructions  │  -0% │
  │        │ 1370MB peak RSS            │ 1261MB peak RSS            │  -8% │
  ├────────┼────────────────────────────┼────────────────────────────┼──────┤
  │ 2095¹¹ │ 2m10s                      │ 2m11s                      │  +1% │
  │        │ 74871386805 instructions   │ 74549569707 instructions   │  -0% │
  │        │ 113MB peak RSS             │ 92MB peak RSS              │ -19% │
  └────────┴────────────────────────────┴────────────────────────────┴──────┘

Gitlab: closes #2302

¹ `dot -Tsvg -o /dev/null tests/regression_tests/large/long_chain`.
² “long” in the table is a graph generated by the following script:

    print("digraph {")
    for i in range(80000):
      print(f"  N{i} -> N{i + 1}")
    print("}")

  This represents something like a best case scenario to observe the effect of
  this optimization. Lots of small unique strings. Run as
  `dot -Tsvg -o /dev/null long.dot`.
³ The test case from https://gitlab.com/graphviz/graphviz/-/issues/456 run as
  `dot -Tsvg -o /dev/null 456.dot`. Note that this actually errors out
  eventually.
⁴ The test case from https://gitlab.com/graphviz/graphviz/-/issues/456 but with
  `concentrate=true` removed. Run as `dot -Tsvg -o /dev/null 456.dot`.
⁵ The test case from https://gitlab.com/graphviz/graphviz/-/issues/1652 run as
  `neato -Tsvg -o /dev/null 1652.dot`.
⁶ The test case from https://gitlab.com/graphviz/graphviz/-/issues/1652 run as
  `dot -Tsvg -Gnslimit=2.0 -o /dev/null 1652.dot`. Note that this eventually
  crashes.
⁷ swedish-flat.dot Magnus attached to
  https://gitlab.com/graphviz/graphviz/-/issues/1718 run as
  `circo -Tsvg -o /dev/null swedish-flag.dot`.
⁸ The test case from https://gitlab.com/graphviz/graphviz/-/issues/1864 run as
  `neato -Tsvg -o /dev/null 1864.dot`.
⁹ The test case from https://gitlab.com/graphviz/graphviz/-/issues/1864 run as
  `twopi -Tsvg -o /dev/null 1864.dot`.
¹⁰ The test case from https://gitlab.com/graphviz/graphviz/-/issues/2064 run as
  `dot -Gnslimit=2 -Gnslimit1=2 -Gmaxiter=5000 -Tsvg -o /dev/null 2064.dot`.
¹¹The tests/2095.dot test case from prior to minimization
  (3819821ea70fae730dd224936628ed3929b03531). Run as
  `dot -Tsvg -o /dev/null 2095.dot`.

2 years agocgraph agxbuf: expand usable inline storage
Matthew Fernandez [Thu, 15 Dec 2022 16:49:04 +0000 (08:49 -0800)]
cgraph agxbuf: expand usable inline storage

As indicated by the changes to the layout diagram in this diff, previously we
were essentially wasting a number of bytes (3 on x86, 7 on x86-64) on structure
padding. Through some rearrangement and packing, we can make these bytes usable
for the inline storage area.

The definition of the struct is not quite what you might expect to see. The
`located` field is in the first member of the union but is actually used
regardless of what mode an `agxbuf` is in (heap, stack, inline). This is
necessary to get the desired packing. It does not overlap with other struct
fields, though reading and writing a struct through different union members is
well defined in C99.

This optimization might seem a little niche. But `agxbuf` objects are
extensively used. Once inline `agxbuf` objects become possible (an upcoming
commit), this saves us heap allocations in numerous scenarios.

Gitlab: #2302

2 years agocgraph agxbuf: support storing short strings inline
Matthew Fernandez [Sat, 10 Sep 2022 20:54:55 +0000 (13:54 -0700)]
cgraph agxbuf: support storing short strings inline

This commit implements Small String Optimization (SSO) for `axgbuf`. Strings
up to a certain size (24 bytes unterminated on x86-64) can be stored inline
within an `agxbuf` structure itself with no external backing memory.

There is currently no way to create a buffer in inline mode. Neither
`agxbuf_init` nor zero-initialization gives a path to this. The ability to
create inline strings will be added in an upcoming commit.

When a string is stored inline, its size is maintained in the `located` field
instead of in the `size` field.

Gitlab: #2302

2 years agoCI: suppress -Wmissing-braces in CentOS 7 CMake build
Matthew Fernandez [Thu, 8 Sep 2022 00:27:49 +0000 (17:27 -0700)]
CI: suppress -Wmissing-braces in CentOS 7 CMake build

The compiler on CentOS 7 is an older version of GCC, 4.8.5, which spuriously
issues warnings for code like `foo_t x = {0}` where `foo_t` is a struct
containing an aggregate (array, struct, union). This form of initialization is
meant to be valid for all structs in C99. We need to suppress this to avoid CI
warnings that fail the build in an upcoming commit.

Gitlab: #2302

2 years agocgraph agxbuf: remove an open coded 'agxbclear'
Matthew Fernandez [Thu, 15 Dec 2022 16:30:20 +0000 (08:30 -0800)]
cgraph agxbuf: remove an open coded 'agxbclear'

This will ease some upcoming changes.

Gitlab: #2302

2 years agocgraph agxbuf: rearrange 'agxbclear'
Matthew Fernandez [Thu, 15 Dec 2022 16:26:21 +0000 (08:26 -0800)]
cgraph agxbuf: rearrange 'agxbclear'

This will enable de-duplicating some code in an upcoming commit.

Gitlab: #2302

2 years agocgraph agxbuf: abstract calculation of the capacity of a backing store
Matthew Fernandez [Sat, 10 Sep 2022 20:04:34 +0000 (13:04 -0700)]
cgraph agxbuf: abstract calculation of the capacity of a backing store

This looks a bit like overkill. However, an upcoming commit will make how we
determine this capacity conditional.

Gitlab: #2302

2 years agocgraph agxbuf: use an enumerated type for buffer location
Matthew Fernandez [Sat, 10 Sep 2022 19:04:14 +0000 (12:04 -0700)]
cgraph agxbuf: use an enumerated type for buffer location

This does not change the semantics; 0 still means heap-allocated and 1 means
stack-allocated. However this is preparation for introducing a third location a
buffer can be hosted in.

Gitlab: #2302

2 years agocgraph: use size+capacity for agxbuf instead of a pair of pointers
Matthew Fernandez [Sat, 10 Dec 2022 04:40:54 +0000 (20:40 -0800)]
cgraph: use size+capacity for agxbuf instead of a pair of pointers

This simplifies some code and will also enable some upcoming optimizations.

Gitlab: #2302

2 years agogvpr deparse: avoid accessing agxbuf internals
Matthew Fernandez [Sat, 17 Dec 2022 20:00:39 +0000 (12:00 -0800)]
gvpr deparse: avoid accessing agxbuf internals

This eases some upcoming changes to the internal structure of the `agxbuf` type.
This alters the semantics of `deparse` (the buffer’s size ends up 0 on
completion of this function), but this is acceptable as all callers go on to
immediately free the buffer.

Gitlab: #2302

2 years agocgraph: simplify error handling to let 'agxbprint' do string clamping
Matthew Fernandez [Sat, 17 Dec 2022 19:57:39 +0000 (11:57 -0800)]
cgraph: simplify error handling to let 'agxbprint' do string clamping

2 years agocgraph: avoid accessing agxbuf internals in the scanner
Matthew Fernandez [Sat, 17 Dec 2022 19:53:19 +0000 (11:53 -0800)]
cgraph: avoid accessing agxbuf internals in the scanner

This eases some upcoming changes to the internal structure of the `agxbuf` type.
The trailing calls to `agxbclear` are removed because they are no longer
necessary; the `agxbuse` call does the same thing.

Gitlab: #2302

2 years agocommon protect_rsqb: avoid accessing agxbuf internals
Matthew Fernandez [Sat, 10 Dec 2022 04:50:53 +0000 (20:50 -0800)]
common protect_rsqb: avoid accessing agxbuf internals

Avoiding this will ease some upcoming changes.

Gitlab: #2302

2 years agocommon: fix invalid use of 'memcpy' in 'printTok'
Matthew Fernandez [Thu, 15 Dec 2022 06:15:37 +0000 (22:15 -0800)]
common: fix invalid use of 'memcpy' in 'printTok'

1349b895eca0bb04855ba46162d0ec7ba3c65010 refactored `printTok` to introduce a
call to `agxbput` that passes in the return value from a previous `agxbuse` on
the same buffer. This pointer still points into the destination buffer and
`agxbput` bottoms out on a call to `memcpy`. So this ends up calling `memcpy`
with overlapping source and destination, something that is undefined behavior in
C.

This change introduces a local alternative for this situation, because this is
the only known place where we need to do such a thing.

Gitlab: #2302, fixes #2326

2 years agocommon protect_rsqb: remove an open coded 'agxblen'
Matthew Fernandez [Sat, 10 Dec 2022 04:41:44 +0000 (20:41 -0800)]
common protect_rsqb: remove an open coded 'agxblen'

Gitlab: #2302

2 years agocgraph: remove initial '\0' store to new agxbuf
Matthew Fernandez [Sat, 10 Dec 2022 04:08:04 +0000 (20:08 -0800)]
cgraph: remove initial '\0' store to new agxbuf

Nothing in the code base relies on this. Callers always use `agxbuse` before
relying on the buffer being NUL terminated.

Gitlab: #2302

2 years agocgraph agxblen: de-duplicate some logic that was effectively 'agxblen'
Matthew Fernandez [Sat, 10 Sep 2022 19:41:51 +0000 (12:41 -0700)]
cgraph agxblen: de-duplicate some logic that was effectively 'agxblen'

Gitlab: #2302

2 years agocgraph agxbuf: relocate 'agxblen'
Matthew Fernandez [Sat, 10 Sep 2022 19:31:50 +0000 (12:31 -0700)]
cgraph agxbuf: relocate 'agxblen'

A number of other functions in agxbuf.h open code the logic of `agxblen`. Moving
this function higher in the header will enable us to de-duplicate this code. The
goal here is to fully abstract this, as an upcoming commit will make the way the
length of an `agxbuf` is calculated conditional.

Gitlab: #2302

2 years agoadd a variant of #2272 test case
Matthew Fernandez [Sat, 17 Dec 2022 19:34:18 +0000 (11:34 -0800)]
add a variant of #2272 test case

While working on Small String Optimization, it became clear that a variant of
this test case which just passes an invalid string through the Graphviz binary
provokes some non-trivial behavior which is worth testing.

Gitlab: #2272

2 years agoMerge branch 'smattr/2ef8644c-67d1-4321-83df-83d7b7cf8d78' into 'main'
Matthew Fernandez [Sun, 18 Dec 2022 04:17:49 +0000 (04:17 +0000)]
Merge branch 'smattr/2ef8644c-67d1-4321-83df-83d7b7cf8d78' into 'main'

cgraph: remove unimplemented 'attrmacro' in the grammar

See merge request graphviz/graphviz!3002

2 years agocgraph: remove now unnecessary 'attritem' indirection in the grammar
Matthew Fernandez [Sat, 17 Dec 2022 18:58:05 +0000 (10:58 -0800)]
cgraph: remove now unnecessary 'attritem' indirection in the grammar

2 years agocgraph: remove unimplemented 'attrmacro' in the grammar
Matthew Fernandez [Sat, 17 Dec 2022 18:53:23 +0000 (10:53 -0800)]
cgraph: remove unimplemented 'attrmacro' in the grammar

Parsing this entity would result in calling `appendattr` in a way that failed an
assertion. Thankfully it is unimplemented, so this is unreachable. However, it
is also not practical anymore to implement this. The lexer (lib/cgraph/scan.l)
treats `@` as an end-of-file marker. So future modifications to the DOT language
to interpret `@` as an attribute macro would break a lot of existing things.

2 years agoMerge branch 'layout' into 'main'
Matthew Fernandez [Wed, 14 Dec 2022 17:31:14 +0000 (17:31 +0000)]
Merge branch 'layout' into 'main'

Doxygen for layout engines

See merge request graphviz/graphviz!2882

2 years agodoxygen for twopigen
Costa Shulyupin [Thu, 6 Oct 2022 18:57:02 +0000 (21:57 +0300)]
doxygen for twopigen

2 years agodoxygen for sfdpgen
Costa Shulyupin [Thu, 6 Oct 2022 18:56:38 +0000 (21:56 +0300)]
doxygen for sfdpgen

2 years agodoxygen for patchwork
Costa Shulyupin [Thu, 6 Oct 2022 18:55:11 +0000 (21:55 +0300)]
doxygen for patchwork

2 years agodoxygen for osage
Costa Shulyupin [Thu, 6 Oct 2022 18:54:47 +0000 (21:54 +0300)]
doxygen for osage

2 years agodoxygen for neatogen
Costa Shulyupin [Thu, 6 Oct 2022 18:54:23 +0000 (21:54 +0300)]
doxygen for neatogen

2 years agodoxygen for fdpgen
Costa Shulyupin [Thu, 6 Oct 2022 18:50:53 +0000 (21:50 +0300)]
doxygen for fdpgen

Add exported API functions to file description.

2 years agodoxygen for circogen
Costa Shulyupin [Thu, 6 Oct 2022 18:50:23 +0000 (21:50 +0300)]
doxygen for circogen

Add exported API functions to file description.

Move references to the bottom because they belong to
whole directory, not just the file.

2 years agodoxygen for dotgen
Costa Shulyupin [Thu, 6 Oct 2022 18:48:12 +0000 (21:48 +0300)]
doxygen for dotgen

2 years agoMerge branch 'smattr/d26e56b1-b7a2-4e5a-869b-841e0311d45c' into 'main'
Matthew Fernandez [Wed, 14 Dec 2022 06:15:31 +0000 (06:15 +0000)]
Merge branch 'smattr/d26e56b1-b7a2-4e5a-869b-841e0311d45c' into 'main'

cgraph: pass destructor as a macro parameter instead of struct member

See merge request graphviz/graphviz!2999

2 years agocgraph: pass destructor as a macro parameter instead of struct member
Matthew Fernandez [Sun, 11 Dec 2022 20:27:52 +0000 (12:27 -0800)]
cgraph: pass destructor as a macro parameter instead of struct member

This smoothes down a number of rough edges in the generic list implementation:

  1. No need to noisily cast e.g. `free` as a destructor at the initialization
     site.

  2. The generic list struct is reduced by the size of a function pointer. This
     is not significant when a list is used entirely locally as the compiler can
     destructure this type as an optimization. But when passing objects of this
     type between functions, this can help.

  3. Some functions like free of the generic list zeroed the structure, losing
     the destructor. This could be improved by retaining it, but it seemed
     simpler to remove the opportunity for this confusion altogether.

An alternative to creating the new `DEFINE_LIST_WITH_DTOR` macro would be to
implement `DEFINE_LIST` as a variadic macro, taking an optional third parameter.
However the gymnastics required to achieve this in C99 (search the internet for
macro argument counting) make it not worth it.

2 years agoMerge branch 'smattr/gitlab-2325' into 'main'
Matthew Fernandez [Wed, 14 Dec 2022 02:01:14 +0000 (02:01 +0000)]
Merge branch 'smattr/gitlab-2325' into 'main'

fix out-of-bounds memory reads with large 'style' strings

Closes #2325

See merge request graphviz/graphviz!3000

2 years agocgraph: remove no longer used 'agxbnext'
Matthew Fernandez [Sun, 11 Dec 2022 20:47:02 +0000 (12:47 -0800)]
cgraph: remove no longer used 'agxbnext'

2 years agocommon parse_style: more tightly scope 'ps_xb'
Matthew Fernandez [Sun, 11 Dec 2022 19:54:19 +0000 (11:54 -0800)]
common parse_style: more tightly scope 'ps_xb'

2 years agocommon parse_style: remove static backing buffer for 'ps_xb'
Matthew Fernandez [Sun, 11 Dec 2022 19:51:31 +0000 (11:51 -0800)]
common parse_style: remove static backing buffer for 'ps_xb'

There seems little value retaining this when it adds complication and was a
contributing factor in the bug just fixed. This potentially slightly degrades
performance (initial style use results in a heap allocation), but is unlikely to
be measurable and should be regained back if we implement Small String
Optimization on `agxbuf`.

2 years agofix out-of-bounds memory reads with large 'style' strings
Matthew Fernandez [Sun, 11 Dec 2022 19:42:01 +0000 (11:42 -0800)]
fix out-of-bounds memory reads with large 'style' strings

Parsing a large style would acquire pointers into the `agxbuf` it wrote into,
but then go on to append more data to the buffer, potentially triggering a
reallocation thus leaving those prior pointers dangling. Later attempts to
access the style would read from these (now invalid) pointers. This bug has
existed since the very first commit of Graphviz.

Note that this change does nothing to alter the NUL-separated-string design of
the return value of `parse_style`. This still remains because some callers rely
on it, despite it being known as problematic.

Gitlab: fixes #2325

2 years agocommon parse_stlye: use a more appropriate type for counting styles
Matthew Fernandez [Sun, 11 Dec 2022 19:32:21 +0000 (11:32 -0800)]
common parse_stlye: use a more appropriate type for counting styles

2 years agoadd a test case for #2325
Matthew Fernandez [Sun, 11 Dec 2022 19:25:26 +0000 (11:25 -0800)]
add a test case for #2325

This currently triggers an out-of-bounds read, observable with ASan.

2 years agoMerge branch 'smattr/550b8768-ca04-4379-9b05-291ecd1d9c6e' into 'main'
Matthew Fernandez [Wed, 14 Dec 2022 01:03:05 +0000 (01:03 +0000)]
Merge branch 'smattr/550b8768-ca04-4379-9b05-291ecd1d9c6e' into 'main'

cgraph: remove 'agxbstart'

See merge request graphviz/graphviz!2997

2 years agocgraph: remove no longer used 'agxbstart'
Matthew Fernandez [Sat, 10 Dec 2022 21:01:57 +0000 (13:01 -0800)]
cgraph: remove no longer used 'agxbstart'

2 years agocommon printTok: remove use of 'agxbstart' to access agxbuf data
Matthew Fernandez [Sat, 10 Dec 2022 20:54:40 +0000 (12:54 -0800)]
common printTok: remove use of 'agxbstart' to access agxbuf data

Reaching into something that is notionally the internals of the `agxbuf` type
was causing some complications in upcoming changes. Specifically, the lifetime
of the pointer returned from `agxbstart` makes it error prone. Any operation
that appends more data to the `agxbuf` must conservatively be assumed to
invalidate a pointer previously returned from `agxbstart`.

Although this instance was not retaining the returned pointer, the `agxbstart`
interface seems dangerous to provide given that it is difficult to use safely.
By removing its sole use here, we clear the way for its removal in future.

This new phrasing is potentially less efficient, as data is now extracted from
the buffer and then written back into the same buffer. However (1) a good
contemporary compiler will inline all calls and realize the accumulated
operation on the buffer is a no-op and (2) this is debug code, so performance is
not critical.

Gitlab: related to #2325

2 years agoMerge branch 'smattr/900d5d7b-5f27-4dc3-be4b-9934e4be9906' into 'main'
Matthew Fernandez [Sun, 11 Dec 2022 19:24:42 +0000 (19:24 +0000)]
Merge branch 'smattr/900d5d7b-5f27-4dc3-be4b-9934e4be9906' into 'main'

use list.h to replace various integer stack implementations

See merge request graphviz/graphviz!2996

2 years agosparse: fix comment typo
Matthew Fernandez [Sat, 10 Dec 2022 20:41:07 +0000 (12:41 -0800)]
sparse: fix comment typo

2 years agocgraph: add unit tests for list.h API
Matthew Fernandez [Sat, 10 Dec 2022 20:38:04 +0000 (12:38 -0800)]
cgraph: add unit tests for list.h API

2 years agocgraph: fix incorrect shrink-to-fit implementation for lists
Matthew Fernandez [Sat, 10 Dec 2022 20:35:32 +0000 (12:35 -0800)]
cgraph: fix incorrect shrink-to-fit implementation for lists

This was accidentally a no-op due to a comparison that was always false.

2 years agocgraph: fix incorrect resize-down implementation for lists without destructors
Matthew Fernandez [Sat, 10 Dec 2022 20:33:16 +0000 (12:33 -0800)]
cgraph: fix incorrect resize-down implementation for lists without destructors

Attempting to shrink a list that did not have a element destructor would
incorrectly do nothing.

2 years agogvgen: replace 'gv_stack_t' with generic list for int stack
Matthew Fernandez [Thu, 8 Dec 2022 16:35:26 +0000 (08:35 -0800)]
gvgen: replace 'gv_stack_t' with generic list for int stack

The generic list implementation is an improvement over `gv_stack_t` in that it
is both more flexible and type safe. Migrating to it has two primary
improvements:

  1. Maintaining type safety. There is now no need to cast when pushing and
     popping the stack. This removes two compiler warnings and leads to shorter,
     more readable code.

  2. Memory reduction. On 64-bit platforms with a 32-bit int (e.g. x86-64),
     `gv_stack_t` uses 8 bytes per int element for storage. In contrast, the
     generic list uses 4 bytes per int.

2 years agosparse: replace 'IntStack' with generic list implementation
Matthew Fernandez [Thu, 8 Dec 2022 16:24:53 +0000 (08:24 -0800)]
sparse: replace 'IntStack' with generic list implementation

Apart from reducing the amount of code to maintain going forwards, this removes
several warts:

  1. `IntStack_push` returned a value indicating whether it succeeded or failed.
     The caller was ignoring this. We now exit on push failure.

  2. `IntStack_pop` used an awkward flag-based protocol to detect an empty
     stack. We now use a cleaner “is empty” guard on the pop call.

  3. Iterating over all stack elements sometimes used < length and sometimes
     ≤ last. There were reasons for this (`SIZE_MAX` was used as a sentinel
     last value, and length was calculated based on last). But it led to code
     that was harder than necessary to understand at the call site.

2 years agocgraph: add push and pop functions to the generic list
Matthew Fernandez [Thu, 8 Dec 2022 16:03:22 +0000 (08:03 -0800)]
cgraph: add push and pop functions to the generic list

This enables using this data structure as a stack as well. In future it could
grow to replace `gv_stack_t`.

2 years agoMerge branch 'smattr/7522e5d4-990f-4626-90b9-08632f4d552f' into 'main'
Matthew Fernandez [Sun, 11 Dec 2022 18:35:26 +0000 (18:35 +0000)]
Merge branch 'smattr/7522e5d4-990f-4626-90b9-08632f4d552f' into 'main'

CI: hard code platform when running './configure' on Cygwin

See merge request graphviz/graphviz!2998

2 years agoCI: hard code platform when running './configure' on Cygwin
Matthew Fernandez [Sat, 10 Dec 2022 22:04:10 +0000 (14:04 -0800)]
CI: hard code platform when running './configure' on Cygwin

The Cygwin Autotools builds have begun failing in CI:

  + ./configure --prefix=/cygdrive/c/GitLab-Runner/builds/smattr/graphviz/
    graphviz-7.0.5~dev.20221210.2041/build
  checking build system type... config/config.guess: unable to guess system type

  This script (version 2018-02-24), has failed to recognize the
  operating system you are using. If your script is old, overwrite *all*
  copies of config.guess and config.sub with the latest versions from:

    https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
  and
    https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub

  If config/config.guess has already been updated, send the following data and any
  information you think might be pertinent to config-patches@gnu.org to
  provide the necessary information to handle your system.

  config.guess timestamp = 2018-02-24

  uname -m = .x86_64
  uname -r = 3.4.1-1.x86_64
  uname -s = CYGWIN_NT-10.0-17763
  uname -v = 2022-12-10 19:59 UTC

  /usr/bin/uname -p = unknown
  /bin/uname -X     =

  hostinfo               =
  /bin/universe          =
  /usr/bin/arch -k       =
  /bin/arch              = .x86_64
  /usr/bin/oslevel       =
  /usr/convex/getsysinfo =

  UNAME_MACHINE = ".x86_64"
  UNAME_RELEASE = "3.4.1-1.x86_64"
  UNAME_SYSTEM  = "CYGWIN_NT-10.0-17763"
  UNAME_VERSION = "2022-12-10 19:59 UTC"
  configure: error: cannot guess build type; you must specify one

config.guess is one of those scripts that is manually copy-pasted between GNU
projects. In this instance, it is the copy within Automake that is being used.
CI appears to be installing the very latest version of Automake at time of
writing (1.16.5), so upgrading Automake is not a fix here.

Cross referencing the upstream version of config.guess in Savannah¹, there have
been a lot of changes to this file since the version Automake is carrying². But
none of them jump out as something that would affect Cygwin detection in this
way.

So this commit works around the problem on our side. We hard code the guess that
`./configure` should have made. Note that this change uses the guess text from
the newer config.guess, `x86_64-pc-cygwin`, instead of the guess text from the
older version of config.guess Automake is carrying, `x86_64-unknown-cygwin`.

If this problem turns out to have a root cause in Automake and is fixed in
future, we should be able to revert this change.

¹ https://savannah.gnu.org/projects/config/
² 72 commits touching this file since the version Automake is carrying
  (2018-02-24). Total diff of these commits to config.guess is 2143 lines.

2 years agoMerge branch 'smattr/71c7f362-abcc-458d-b5e3-5fc6624fc5f6' into 'main'
Matthew Fernandez [Thu, 8 Dec 2022 04:26:13 +0000 (04:26 +0000)]
Merge branch 'smattr/71c7f362-abcc-458d-b5e3-5fc6624fc5f6' into 'main'

prune: fix memory leaks in list destruction

See merge request graphviz/graphviz!2992

2 years agoprune: fix memory leaks in list destruction
Matthew Fernandez [Tue, 6 Dec 2022 15:23:21 +0000 (07:23 -0800)]
prune: fix memory leaks in list destruction

This problem seems to have existed since the first Graphviz commit.

2 years agocgraph: add support for per-element destructors in list implementation
Matthew Fernandez [Tue, 6 Dec 2022 15:18:51 +0000 (07:18 -0800)]
cgraph: add support for per-element destructors in list implementation

2 years agoMerge branch 'smattr/b354fca9-3b7d-44bb-b58f-90a35847a3f9' into 'main'
Matthew Fernandez [Thu, 8 Dec 2022 02:03:07 +0000 (02:03 +0000)]
Merge branch 'smattr/b354fca9-3b7d-44bb-b58f-90a35847a3f9' into 'main'

osage: roll out cgraph allocation wrapper usage

See merge request graphviz/graphviz!2989

2 years agoosage layout: remove unnecessary casts
Matthew Fernandez [Sun, 4 Dec 2022 22:25:31 +0000 (14:25 -0800)]
osage layout: remove unnecessary casts

2 years agoosage layout: use cgraph wrappers for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
osage layout: use cgraph wrappers for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agoosage: replace clist implementation with generic list
Matthew Fernandez [Sat, 3 Dec 2022 18:54:23 +0000 (10:54 -0800)]
osage: replace clist implementation with generic list

This replaces some common/memory.h allocations with cgraph/alloc.h, but more
importantly reduces the amount of code to maintain here. Note that confusingly
the list begins with a NULL entry and is only relevant to store later if we have
accrued more than just the initial NULL.

This is the equivalent of b10b254860b2bcbc85b9779a2388d33ce8318908 but applied
to osage.

2 years agoosage: inline 'initCList' into a C99 initialization
Matthew Fernandez [Thu, 1 Dec 2022 04:46:33 +0000 (20:46 -0800)]
osage: inline 'initCList' into a C99 initialization

This is the equivalent of 4460351650475f4e8aa4ef085928e1697776f070 but applied
to osage.

2 years agoMerge branch 'smattr/2fd01708-69d8-41fe-a59b-d701cf5b5c6c' into 'main'
Matthew Fernandez [Thu, 8 Dec 2022 01:12:10 +0000 (01:12 +0000)]
Merge branch 'smattr/2fd01708-69d8-41fe-a59b-d701cf5b5c6c' into 'main'

fdpgen, neatogen: some cgraph alloc wrapper migration, bug fixing, type adjustment

See merge request graphviz/graphviz!2991

2 years agoneatogen: remove some unnecessary parens
Matthew Fernandez [Tue, 6 Dec 2022 05:39:28 +0000 (21:39 -0800)]
neatogen: remove some unnecessary parens

2 years agoneatogen computeScale: swap 'MIN' for stdlib equivalent
Matthew Fernandez [Tue, 6 Dec 2022 05:39:11 +0000 (21:39 -0800)]
neatogen computeScale: swap 'MIN' for stdlib equivalent

2 years agoneatogen computeScaleXY: swap 'MAX' for stdlib equivalent
Matthew Fernandez [Tue, 6 Dec 2022 05:38:42 +0000 (21:38 -0800)]
neatogen computeScaleXY: swap 'MAX' for stdlib equivalent

2 years agoneatogen computeScale: use cgraph wrapper for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
neatogen computeScale: use cgraph wrapper for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agoneatogen computeScaleXY: use cgraph wrapper for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
neatogen computeScaleXY: use cgraph wrapper for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agoneatogen cAdjust: use cgraph wrapper for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
neatogen cAdjust: use cgraph wrapper for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agoneatogen mkOverlapSet: replace manual array with list implementation
Matthew Fernandez [Tue, 6 Dec 2022 05:23:23 +0000 (21:23 -0800)]
neatogen mkOverlapSet: replace manual array with list implementation

2 years agoneatogen mkOverlapSet: return actual point count in 'cntp'
Matthew Fernandez [Tue, 6 Dec 2022 05:16:46 +0000 (21:16 -0800)]
neatogen mkOverlapSet: return actual point count in 'cntp'

For reasons unclear to me, the `mkOverlapSet` function was constructing a set of
points with an implicit initial 0 point and then notifying the caller of a count
1 _less_ than the total point count. There was nothing wrong with this, but it
led to several instances of non-idiomatic follow-on code that had to account for
an array that was actually 1 longer than what its count variable said.

2 years agoneatogen computeScaleXY: fix memory leak
Matthew Fernandez [Tue, 6 Dec 2022 05:00:31 +0000 (21:00 -0800)]
neatogen computeScaleXY: fix memory leak

2 years agoneatogen constraint: use 'size_t' to count points
Matthew Fernandez [Tue, 6 Dec 2022 04:58:23 +0000 (20:58 -0800)]
neatogen constraint: use 'size_t' to count points

Squashes five -Wsign-conversion warnings. This requires a few cascading changes
to various callees here.

2 years agofdpgen: replace clist implementation with generic list
Matthew Fernandez [Sat, 3 Dec 2022 18:54:23 +0000 (10:54 -0800)]
fdpgen: replace clist implementation with generic list

This replaces some common/memory.h allocations with cgraph/alloc.h, but more
importantly reduces the amount of code to maintain here. Note that confusingly
the list begins with a NULL entry and is only relevant to store later if we have
accrued more than just the initial NULL.

This is the equivalent of b10b254860b2bcbc85b9779a2388d33ce8318908 but applied
to fdpgen.

2 years agofdpgen: inline 'initCList' into a C99 initialization
Matthew Fernandez [Thu, 1 Dec 2022 04:46:33 +0000 (20:46 -0800)]
fdpgen: inline 'initCList' into a C99 initialization

This is the equivalent of 4460351650475f4e8aa4ef085928e1697776f070 but applied
to fdpgen.

2 years agoMerge branch 'smattr/53ae5c5d-ba33-4ab5-b844-dc0d40fc5e1c' into 'main'
Matthew Fernandez [Tue, 6 Dec 2022 01:00:48 +0000 (01:00 +0000)]
Merge branch 'smattr/53ae5c5d-ba33-4ab5-b844-dc0d40fc5e1c' into 'main'

cgraph: inline 'bitarray_new' into 'bitarray_new_or_exit' and rename

See merge request graphviz/graphviz!2990

2 years agocgraph: inline 'bitarray_new' into 'bitarray_new_or_exit' and rename
Matthew Fernandez [Mon, 5 Dec 2022 02:28:29 +0000 (18:28 -0800)]
cgraph: inline 'bitarray_new' into 'bitarray_new_or_exit' and rename

All clients of this functionality were calling `bitarray_new_or_exit`. That is,
none of them could cope with failure. In the intervening time since this API was
added, several other exit-on-failure functions have sprung up. For example,
`gv_alloc`. It seems reasonable to now abbreviate this, leading to lesser code
to maintain, with the “or exit” now implicit.

2 years agoMerge branch 'smattr/bbedf005-c240-4739-a365-79e0b6b009c9' into 'main'
Matthew Fernandez [Mon, 5 Dec 2022 00:25:45 +0000 (00:25 +0000)]
Merge branch 'smattr/bbedf005-c240-4739-a365-79e0b6b009c9' into 'main'

twopigen: use cgraph wrappers for allocation

See merge request graphviz/graphviz!2982

2 years agotwopigen: use an exact comparison when testing against 'UNSET'
Matthew Fernandez [Tue, 29 Nov 2022 01:27:53 +0000 (17:27 -0800)]
twopigen: use an exact comparison when testing against 'UNSET'

Squashes a -Wfloat-comparison warning.

2 years agotwopigen: use a 'uint64_t' for infinity sentinel
Matthew Fernandez [Tue, 29 Nov 2022 01:26:18 +0000 (17:26 -0800)]
twopigen: use a 'uint64_t' for infinity sentinel

This value is guaranteed to not be negative (an `int` multiplied by itself is
non-negative) and later is compared against `uint64_t` values. So this change
squashes a couple of warnings.

2 years agotwopigen twopi_init_node_edge: use cgraph wrappers for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
twopigen twopi_init_node_edge: use cgraph wrappers for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agotwopigen getRankseps: use cgraph wrapper for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
twopigen getRankseps: use cgraph wrapper for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agotwopigen push: use cgraph wrapper for allocation
Matthew Fernandez [Fri, 18 Nov 2022 01:14:41 +0000 (17:14 -0800)]
twopigen push: use cgraph wrapper for allocation

The lib/cgraph/alloc.h wrappers are similar to the older lib/common/memory.h
wrappers except (1) they are header-only and (2) they live in a directory
(cgraph) that is at the root of the dependency tree. The long term plan is to
replace all use of lib/common/memory.h with lib/cgraph/alloc.h.

2 years agoMerge branch 'smattr/9a665a71-ab78-4631-aefe-acabc4924775' into 'main'
Matthew Fernandez [Sun, 4 Dec 2022 23:33:40 +0000 (23:33 +0000)]
Merge branch 'smattr/9a665a71-ab78-4631-aefe-acabc4924775' into 'main'

cgraph: squash -Wunused-function warnings for list functions

See merge request graphviz/graphviz!2988

2 years agocgraph: squash -Wunused-function warnings for list functions
Matthew Fernandez [Sun, 4 Dec 2022 21:31:38 +0000 (13:31 -0800)]
cgraph: squash -Wunused-function warnings for list functions

Clang on macOS seems to complain about even `inline` functions when they are
defined within a .c file.

2 years agoMerge branch 'gshklover_simplex' into 'main'
Matthew Fernandez [Sun, 4 Dec 2022 19:55:54 +0000 (19:55 +0000)]
Merge branch 'gshklover_simplex' into 'main'

Modified dfs_range() in ns.c to prune unmodified sub-trees

See merge request graphviz/graphviz!2857

2 years agoModified dfs_range() in ns.c to prune unmodified sub-trees
greg [Mon, 26 Sep 2022 12:14:14 +0000 (15:14 +0300)]
Modified dfs_range() in ns.c to prune unmodified sub-trees

2 years agoMerge branch 'smattr/50455448-28d0-4b1d-87fe-34700fbdc672' into 'main'
Matthew Fernandez [Sun, 4 Dec 2022 18:51:00 +0000 (18:51 +0000)]
Merge branch 'smattr/50455448-28d0-4b1d-87fe-34700fbdc672' into 'main'

rollout cgraph alloc.h headers in patchwork, implement a generic list

See merge request graphviz/graphviz!2986

2 years agoprune: use generalized list implementation for nodes list
Matthew Fernandez [Sat, 3 Dec 2022 19:10:46 +0000 (11:10 -0800)]
prune: use generalized list implementation for nodes list

This allows preserving type safety (no more `char*` casts needed). We can also
entirely remove prune’s generic list implementation which is no longer used.

2 years agoprune: use generalized list implementation for attributes list
Matthew Fernandez [Sat, 3 Dec 2022 19:10:46 +0000 (11:10 -0800)]
prune: use generalized list implementation for attributes list

This allows preserving type safety (no more `strattr_t` casts needed) and the
list items can be managed by value (no more `gv_alloc` for the `sp` being
appended), leading to simpler code.