Changeset 19033 in josm


Ignore:
Timestamp:
2024-04-05T14:58:43+02:00 (5 weeks ago)
Author:
GerdP
Message:

fix #23599: Error opening osm.pbf if way has negative ID or incomplete metadata
This fixes

  • handling of visible flag as proposed by *Martin*
  • handling of completely missing denseinfo (ids are always delta encoded), upload is discouraged
  • handling of denseinfo which only contains version data
Location:
trunk
Files:
6 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/OsmPbfReader.java

    r19024 r19033  
    1616import java.util.Set;
    1717
    18 import jakarta.annotation.Nonnull;
    19 import jakarta.annotation.Nullable;
    20 
    2118import org.apache.commons.compress.utils.CountingInputStream;
    2219import org.openstreetmap.josm.data.Bounds;
     
    3128import org.openstreetmap.josm.data.osm.RelationMemberData;
    3229import org.openstreetmap.josm.data.osm.Tagged;
     30import org.openstreetmap.josm.data.osm.UploadPolicy;
    3331import org.openstreetmap.josm.data.osm.User;
    3432import org.openstreetmap.josm.data.osm.WayData;
     
    4442import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    4543import org.openstreetmap.josm.tools.Utils;
     44
     45import jakarta.annotation.Nonnull;
     46import jakarta.annotation.Nullable;
    4647
    4748/**
     
    523524            if (info != null) {
    524525                setOsmPrimitiveData(primitiveBlockRecord, node, info);
     526            } else {
     527                ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    525528            }
    526529            buildPrimitive(node);
     
    572575            }
    573576        }
     577
    574578        int keyValIndex = 0; // This index must not reset between nodes, and must always increment
    575579        if (ids.length == lats.length && lats.length == lons.length && (denseInfo == null || denseInfo.length == lons.length)) {
     
    579583            for (int i = 0; i < ids.length; i++) {
    580584                final NodeData node;
     585                id += ids[i];
     586                node = new NodeData(id);
    581587                if (denseInfo != null) {
    582588                    Info info = denseInfo[i];
    583                     id += ids[i];
    584                     node = new NodeData(id);
    585589                    setOsmPrimitiveData(primitiveBlockRecord, node, info);
    586590                } else {
    587                     node = new NodeData(ids[i]);
     591                    ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    588592                }
    589593                lat += lats[i];
     
    679683        if (info != null) {
    680684            setOsmPrimitiveData(primitiveBlockRecord, wayData, info);
     685        } else {
     686            ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    681687        }
    682688        buildPrimitive(wayData);
     
    744750        if (info != null) {
    745751            setOsmPrimitiveData(primitiveBlockRecord, data, info);
     752        } else {
     753            ds.setUploadPolicy(UploadPolicy.DISCOURAGED);
    746754        }
    747755        addTags(data, keys, values);
     
    796804                        break;
    797805                    case 6:
    798                         visible = protobufRecord.asUnsignedVarInt().byteValue() == 0;
     806                        visible = protobufRecord.asUnsignedVarInt().byteValue() == 1;
    799807                        break;
    800808                    default: // Fall through, since the PBF format could be extended
     
    947955            }
    948956        }
    949         if (version.length == timestamp.length && timestamp.length == changeset.length && changeset.length == uid.length &&
    950                 uid.length == userSid.length && (visible == EMPTY_LONG || visible.length == userSid.length)) {
     957        if (version.length > 0) {
    951958            Info[] infos = new Info[version.length];
    952959            long lastTimestamp = 0; // delta encoded
     
    955962            long lastUserSid = 0; // delta encoded, string id for username
    956963            for (int i = 0; i < version.length; i++) {
    957                 lastTimestamp += timestamp[i];
    958                 lastChangeset += changeset[i];
    959                 lastUid += uid[i];
    960                 lastUserSid += userSid[i];
     964                if (timestamp.length > i)
     965                    lastTimestamp += timestamp[i];
     966                if (changeset.length > i)
     967                    lastChangeset += changeset[i];
     968                if (uid.length > i && userSid.length > i) {
     969                    lastUid += uid[i];
     970                    lastUserSid += userSid[i];
     971                }
    961972                infos[i] = new Info((int) version[i], lastTimestamp, lastChangeset, (int) lastUid, (int) lastUserSid,
    962973                        visible == EMPTY_LONG || visible[i] == 1);
  • trunk/test/unit/org/openstreetmap/josm/gui/io/importexport/OsmPbfImporterTest.java

    r19024 r19033  
    2424import org.openstreetmap.josm.data.osm.AbstractPrimitive;
    2525import org.openstreetmap.josm.data.osm.DataSet;
     26import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2627import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    2728import org.openstreetmap.josm.data.osm.Relation;
     29import org.openstreetmap.josm.data.osm.UploadPolicy;
    2830import org.openstreetmap.josm.data.osm.Way;
    2931import org.openstreetmap.josm.data.protobuf.ProtobufTest;
     
    159161        assertDoesNotThrow(() -> importer.parseDataSet(new ByteArrayInputStream(badData), NullProgressMonitor.INSTANCE));
    160162    }
     163
     164    @Test
     165    void testNonRegression23599a() throws IOException, IllegalDataException {
     166        final DataSet dataSet;
     167        try (InputStream inputStream = TestUtils.getRegressionDataStream(23599, "visible.osm.pbf")) {
     168            dataSet = importer.parseDataSet(inputStream, NullProgressMonitor.INSTANCE);
     169        }
     170        assertTrue(dataSet.getNodes().stream().allMatch(OsmPrimitive::isVisible));
     171        assertTrue(dataSet.getWays().stream().allMatch(OsmPrimitive::isVisible));
     172        assertTrue(dataSet.getRelations().stream().allMatch(OsmPrimitive::isVisible));
     173
     174    }
     175
     176    @Test
     177    void testNonRegression23599b() throws IOException, IllegalDataException {
     178        final DataSet dataSet;
     179        // osmconvert w1194668585.orig.osm -o=w1194668585.full.osm.pbf
     180        try (InputStream inputStream = TestUtils.getRegressionDataStream(23599, "w1194668585.full.osm.pbf")) {
     181            dataSet = importer.parseDataSet(inputStream, NullProgressMonitor.INSTANCE);
     182        }
     183        assertNotNull(dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY));
     184        assertEquals(145987123, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getChangesetId());
     185        assertEquals(4, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getVersion());
     186        assertEquals(UploadPolicy.NORMAL, dataSet.getUploadPolicy());
     187    }
     188
     189    @Test
     190    void testNonRegression23599c() throws IOException, IllegalDataException {
     191        final DataSet dataSet;
     192        // osmconvert --drop-author w1194668585.orig.osm -o=w1194668585.full.osm.pbf
     193        try (InputStream inputStream = TestUtils.getRegressionDataStream(23599, "w1194668585.drop-author.osm.pbf")) {
     194            dataSet = importer.parseDataSet(inputStream, NullProgressMonitor.INSTANCE);
     195        }
     196        assertNotNull(dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY));
     197        assertEquals(0, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getChangesetId());
     198        assertEquals(4, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getVersion());
     199        assertEquals(UploadPolicy.NORMAL, dataSet.getUploadPolicy());
     200    }
     201
     202    @Test
     203    void testNonRegression23599d() throws IOException, IllegalDataException {
     204        final DataSet dataSet;
     205        // osmconvert --drop-version w1194668585.orig.osm -o=w1194668585.full.osm.pbf
     206        try (InputStream inputStream = TestUtils.getRegressionDataStream(23599, "w1194668585.drop-version.osm.pbf")) {
     207            dataSet = importer.parseDataSet(inputStream, NullProgressMonitor.INSTANCE);
     208        }
     209        assertNotNull(dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY));
     210        assertEquals(0, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getChangesetId());
     211        assertEquals(0, dataSet.getPrimitiveById(1194668585L, OsmPrimitiveType.WAY).getVersion());
     212        assertEquals(UploadPolicy.DISCOURAGED, dataSet.getUploadPolicy());
     213    }
     214
    161215}
Note: See TracChangeset for help on using the changeset viewer.