Skip to content

Possible bug in CCIntMap.union #329

@fpottier

Description

@fpottier

Hello!

This may or may not be a bug, depending on how union is expected to behave. (It currently has no documentation.)

When I call union f m1 m2, I would expect the function f to always be called with a call of the form f k v1 v2 where the value v1 comes from the map m1 and the value v2 comes from the map m2. However, the code does not respect this convention, and can actually issue calls of the form f k v2 v1 where the values are exchanged.

The following example illustrates this:

#require "containers-data";;
open CCIntMap;;

let minus m1 m2 =
  union (fun _key v1 v2 -> v1 - v2) m1 m2;;

let key = 0;;
let m0 = singleton key 1;;       (* a map of [key] to the value 1 *)
let m1 = minus m0 m0;;           (* a map of [key] to the value 0 *)
let m2 = minus m0 m1;;           (* a map of [key] to the value 1 *)
let observed = equal (=) m2 m0;; (* [m0] and [m2] should be equal *)
assert (observed = true);;       (* this fails, but I would expect it to succeed!  *)

Is this a bug? This depends on the specification of union. Does union require its argument f to be commutative? Does union guarantee that f is always applied to a value v1 from the map m1 and a value v2 from the map m2, in this order?

(Bug found by fuzzing with afl-fuzz and the monolith library.)

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions