Conversation
oscpack throws osc::Exception on any malformed input. The parse in OscReceiver::byteArrayToVariantList was unguarded, so a bad datagram unwound through the Qt event loop up to MainApplication::notify(), which aborted the entire readyRead batch and logged unhelpfully. Wrap the parse in a local try/catch: a malformed datagram is now dropped with a clear qWarning, the receive loop keeps draining pending datagrams, and a message is forwarded only when it parsed cleanly.
The event-loop guard already caught std::exception, but logged via qDebug (stripped from release builds) and let non-standard throws escape. Log at qCritical so incidents are visible in shipped builds, add a catch(...) so any exception type is contained, and null-guard the event pointer when reporting the type.
MapMap started its OSC receiver on all interfaces (QHostAddress::Any) at launch, so any device on the venue network could drive mappings or quit the show — OSC has no authentication. Bind to 127.0.0.1 by default and thread an acceptFromNetwork flag through OscInterface into OscReceiver, which widens the bind to all interfaces only when set. Expose it as an "Accept OSC from the network (less secure)" checkbox in Preferences > OSC Setup, off by default. The value is persisted and applied live: PreferenceDialog sets it before setOscPort() rebinds the receiver. Also check the bind() result and log the address.
/mapmap/quit closed the application with no guard, so any OSC sender could end a show. Gate it behind a new "Allow OSC to quit the application" preference (off by default): applyAction now checks isOscQuitAllowed() and drops the quit with a warning otherwise. Wire the setting through MainWindow (persisted) and Preferences > OSC Setup, and document the loopback-by-default and quit-disabled behavior in docs/informations/osc.md.
OscReceiver logged every incoming datagram unconditionally, spamming the log and costing CPU under high OSC rates (e.g. per-frame vertex control). Add a verbose flag to OscReceiver, propagated from OscInterface::setVerbose (driven by the --verbose flag), and only log received messages when it is set. The one-time bind message stays.
MM::VERSION was hardcoded ("0.6.3") and duplicated the qmake VERSION.
Define the human-facing version once (MAPMAP_VERSION in mapmap.pro),
inject it via DEFINES, and have MM::VERSION read it (with a matching
literal fallback for direct compiles). qmake VERSION stays numeric
(1.0.0) so bundle and library versioning remain valid.
Relax SUPPORTED_FILE_VERSIONS to accept an optional -prerelease/+build
suffix and anchor it, so projects saved by 1.0.0-alpha.1 still load and
malformed version strings are rejected explicitly.
Guard the project-file version contract ProjectReader uses to accept or reject a .mmp: MM::SUPPORTED_FILE_VERSIONS must keep matching x.y.z and the pre-release/build suffixes that 1.0.0-alpha.1 writes, while rejecting malformed strings. The unit-test harness deliberately excludes the GUI/multimedia layer, so MappingManager and a full ProjectReader/Writer round-trip cannot link here without a larger harness change; those remain open under QUA-4 in AUDIT.md.
Seven call sites opened a QFile with the result cast to (void), so a missing or locked file silently yielded empty content. Check each open() and qWarning() with the file name on failure. ConsoleWindow::writeLogFile is the exception: it is reached from the installed message handler, so it returns quietly on failure rather than warning (which would recurse).
src.pri is pulled in once per sub-project (.pri), so QMAKE_BUNDLE_DATA gained the syphon_framework entry five times, producing five identical copy rules and make's "overriding commands for target ...Syphon.framework" warnings. Guard the entry with !contains() so it is added once. Regenerating the Makefile now yields a single rule and no warning.
The Spanish catalogue shipped with 0 of 298 strings translated while the app still advertised Spanish support. Translate all 298 UI strings; lrelease now reports 298 finished, 0 unfinished. Note: a few OSC-preference strings added on this branch are not yet in any .ts catalogue; a future lupdate pass is needed to extract and translate them across languages (tracked under QUA-5 in AUDIT.md).
parseSource() and parseLayer() logged a null result from newInstance() and then dereferenced it via ->read(obj), so a corrupt or incompatible .mmp entry whose registered class cannot be instantiated crashed the load. Bail out on a null source/layer instead of calling read(): skip the source with a warning, and report a clear error string for a failed layer so readFile() returns false and the user sees a message.
The embedded MCP HTTP server accepted any request on its loopback port, so any local process — or a web page the operator visited, via a spoofed Host (DNS-rebinding) — could drive MapMap and read project/file metadata. Reject requests whose Host (or Origin, when present) is not loopback, and require an "Authorization: Bearer <token>" header. The token is generated per process at startup and logged alongside the endpoint so a local MCP client can be configured. Note: MCP still starts by default on its port; making it opt-in (port 0 default) remains a separate product decision, tracked under SEC-4 in AUDIT.md.
Both ProjectReader and ProjectWriter use QJsonDocument, so .mmp files are JSON. The datasheet and the English manual still described the save format as XML; correct them. Historical CHANGELOG entries about the original XML-based v0.1 format are left as-is.
DEFAULT_MCP_PORT was 49452, so the MCP HTTP control surface started on every launch. Default it to 0 (disabled); the user opts in by setting a port in Preferences > MCP Setup, which already renders 0 as "Disabled". Also reorder startMcpServer() so port 0 tears down any running server, making a runtime switch to "Disabled" actually stop listening.
Two unchecked reads in the load path: - MShape::read indexed each vertex sub-array as vertex[0]/vertex[1] with no size check, so a malformed [x] or [] entry read out of bounds. Skip vertices that do not have at least two components. - parseProject cast Video/Image sources with Q_CHECK_PTR (a no-op in release builds) and then dereferenced the result, so a corrupt source claiming a media type it cannot cast to would crash. Null-check the cast. Deeper fuzzing of ProjectReader still needs a headless model-layer test harness (tracked with the QUA-4 remainder).
The .ts files were stale (last synced in May), so ~68 in-code strings (Syphon, layer reorder, MCP, the OSC preferences, the professional-services menu items) were never extracted and message locations were out of date. Run lupdate to sync all five catalogues to the current sources. Translate every new string in French and Spanish, including the Syphon plural form: both now report 350/350 finished (0 unfinished). English (the source language) falls back to source text at runtime; Chinese remains partially translated and needs a translator.
Convert the string-based SIGNAL()/SLOT() connects to the compile-checked pointer-to-member syntax in AboutDialog, ConsoleWindow, SourceGui, SyphonServerDialog and MapperGLCanvasToolbar (13 connections). Migrating surfaced a latent bug: the zoom dropdown connected to QComboBox::activated(QString), which Qt 6 removed, so the connection was silently dead. Switch it to &QComboBox::textActivated so "zoom from menu" works again. First QUA-1 increment. MainWindow.cpp (119 connects, many to overloaded signals) and the two overloaded-setValue property-manager connects remain for follow-up commits.
Convert ~123 string-based SIGNAL()/SLOT() connections to the compile-checked pointer-to-member form: MainWindow.cpp (116, including its disconnect() pairs), PreferenceDialog.cpp (5), and the property-manager connects in LayerGui and SourceGui (2, via qOverload for the overloaded setValue slot). The only connection deliberately left string-based is preferencesAction -> PreferenceDialog::exec, whose exec() is a private custom override reachable only that way. With the earlier dialog/toolbar increment, no string-based connects remain outside vendored contrib code (and that one documented exception).
Thirteen menu/action labels used ASCII "..." while newer labels used the Unicode ellipsis "…". Standardize on "…" (the platform convention for a command that opens a dialog before acting). Patch the matching <source> and <translation> entries across all catalogues in lockstep so French and Spanish stay complete (350/350) and the runtime string lookup keeps matching the code.
New WelcomeDialog: on first launch (until the user unticks "Show this window at startup") it greets the user, points at the first steps — "Import a media file…" (emits importMediaRequested, wired to importMedia) and "Read the documentation" — and is reachable any time from Help > "Welcome to MapMap…". The startup preference is stored in QSettings. Note: the bundled example project from the UX-1 spec is intentionally left out for now — it needs a runtime-tested .mmp asset, which cannot be verified in this build-only environment. The new dialog strings still need an lupdate pass to be translated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multiple fixes after I've done an audit.