@bldrs-ai/conway 1.499.1419 → 1.500.1420
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiled/examples/browser-bundled.cjs +1 -4
- package/compiled/examples/cli-bundled.cjs +1 -4
- package/compiled/examples/cli-step-bundled.cjs +1 -4
- package/compiled/examples/validator-bundled.cjs +1 -4
- package/compiled/src/step/parsing/inf_recovery_index.test.d.ts +2 -0
- package/compiled/src/step/parsing/inf_recovery_index.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/inf_recovery_index.test.js +108 -0
- package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_parser.js +32 -3
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -30,7 +30,7 @@ var import_node_process = require("node:process");
|
|
|
30
30
|
var readline = __toESM(require("node:readline"), 1);
|
|
31
31
|
|
|
32
32
|
// compiled/src/version/version.js
|
|
33
|
-
var versionString = "Conway v1.
|
|
33
|
+
var versionString = "Conway v1.500.1420";
|
|
34
34
|
|
|
35
35
|
// compiled/dependencies/conway-geom/interface/conway_geometry.js
|
|
36
36
|
var wasmType = "";
|
|
@@ -2940,9 +2940,6 @@ var StepParser = class extends StepHeaderParser {
|
|
|
2940
2940
|
input2.begin();
|
|
2941
2941
|
const elementResult = parseInlineElement();
|
|
2942
2942
|
if (elementResult !== void 0) {
|
|
2943
|
-
for (const element of elementResult[0].elements) {
|
|
2944
|
-
element.expressID = expressID;
|
|
2945
|
-
}
|
|
2946
2943
|
input2.rollback();
|
|
2947
2944
|
if (tokenws(INF)) {
|
|
2948
2945
|
break;
|
|
@@ -14965,7 +14965,7 @@ ${t5.join("\n")}` : "";
|
|
|
14965
14965
|
var import_process = require("process");
|
|
14966
14966
|
|
|
14967
14967
|
// compiled/src/version/version.js
|
|
14968
|
-
var versionString = "Conway v1.
|
|
14968
|
+
var versionString = "Conway v1.500.1420";
|
|
14969
14969
|
|
|
14970
14970
|
// compiled/dependencies/conway-geom/interface/conway_geometry.js
|
|
14971
14971
|
function pThreadsAllowed() {
|
|
@@ -18754,9 +18754,6 @@ var StepParser = class extends StepHeaderParser {
|
|
|
18754
18754
|
input.begin();
|
|
18755
18755
|
const elementResult = parseInlineElement();
|
|
18756
18756
|
if (elementResult !== void 0) {
|
|
18757
|
-
for (const element of elementResult[0].elements) {
|
|
18758
|
-
element.expressID = expressID;
|
|
18759
|
-
}
|
|
18760
18757
|
input.rollback();
|
|
18761
18758
|
if (tokenws(INF)) {
|
|
18762
18759
|
break;
|
|
@@ -15943,7 +15943,7 @@ var ParsingBuffer = class {
|
|
|
15943
15943
|
};
|
|
15944
15944
|
|
|
15945
15945
|
// compiled/src/version/version.js
|
|
15946
|
-
var versionString = "Conway v1.
|
|
15946
|
+
var versionString = "Conway v1.500.1420";
|
|
15947
15947
|
|
|
15948
15948
|
// compiled/dependencies/conway-geom/interface/conway_geometry.js
|
|
15949
15949
|
function pThreadsAllowed() {
|
|
@@ -18662,9 +18662,6 @@ var StepParser = class extends StepHeaderParser {
|
|
|
18662
18662
|
input.begin();
|
|
18663
18663
|
const elementResult = parseInlineElement();
|
|
18664
18664
|
if (elementResult !== void 0) {
|
|
18665
|
-
for (const element of elementResult[0].elements) {
|
|
18666
|
-
element.expressID = expressID;
|
|
18667
|
-
}
|
|
18668
18665
|
input.rollback();
|
|
18669
18666
|
if (tokenws(INF)) {
|
|
18670
18667
|
break;
|
|
@@ -944,7 +944,7 @@ var EntityTypesIfcCount = 909;
|
|
|
944
944
|
var entity_types_ifc_gen_default = EntityTypesIfc;
|
|
945
945
|
|
|
946
946
|
// compiled/src/version/version.js
|
|
947
|
-
var versionString = "Conway v1.
|
|
947
|
+
var versionString = "Conway v1.500.1420";
|
|
948
948
|
|
|
949
949
|
// compiled/dependencies/conway-geom/interface/conway_geometry.js
|
|
950
950
|
var wasmType = "";
|
|
@@ -3854,9 +3854,6 @@ var StepParser = class extends StepHeaderParser {
|
|
|
3854
3854
|
input.begin();
|
|
3855
3855
|
const elementResult = parseInlineElement();
|
|
3856
3856
|
if (elementResult !== void 0) {
|
|
3857
|
-
for (const element of elementResult[0].elements) {
|
|
3858
|
-
element.expressID = expressID;
|
|
3859
|
-
}
|
|
3860
3857
|
input.rollback();
|
|
3861
3858
|
if (tokenws(INF)) {
|
|
3862
3859
|
break;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inf_recovery_index.test.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/inf_recovery_index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// `INF` where a real belongs is not valid ISO 10303-21, but exporters emit it
|
|
2
|
+
// for unbounded quantities and the parser recovers from it. The recovery used
|
|
3
|
+
// to stamp the offending record's express ID over every top-level entry
|
|
4
|
+
// indexed so far in the block, which corrupted every lookup that followed.
|
|
5
|
+
//
|
|
6
|
+
// It stayed hidden only because no public corpus model reaches this recovery.
|
|
7
|
+
// Not because a failed parse is harmless: the stamping ran before the rollback
|
|
8
|
+
// and the INF check, so any top-level inline-instance failure poisoned the
|
|
9
|
+
// index, and parseDataToModel builds a model from those elements whatever the
|
|
10
|
+
// ParseResult. A private model reaches it - `IFCQUANTITYLENGTH(...,INF,$)`
|
|
11
|
+
// from a Swiss architectural export - where it cost 3,116 entities and
|
|
12
|
+
// produced 630 relationship failures all reporting the same express ID.
|
|
13
|
+
// See bldrs-ai/conway#412, #481, #482.
|
|
14
|
+
//
|
|
15
|
+
// Parser-only, so no geometry wasm is initialized here.
|
|
16
|
+
import { describe, expect, test } from "@jest/globals";
|
|
17
|
+
import IfcStepParser from "../../ifc/ifc_step_parser.js";
|
|
18
|
+
import ParsingBuffer from "../../parsing/parsing_buffer.js";
|
|
19
|
+
import { ParseResult } from "./step_parser.js";
|
|
20
|
+
const parser = IfcStepParser.Instance;
|
|
21
|
+
// The middle record carries the bare INF. The records around it are ordinary,
|
|
22
|
+
// and they are the ones the stamping loop used to overwrite - the bug is not
|
|
23
|
+
// in how the INF record itself is read, it is in what reading it does to
|
|
24
|
+
// everything already indexed.
|
|
25
|
+
// The express IDs under test, kept in one place so the assertions read as
|
|
26
|
+
// "the IDs written in the source", which is exactly what the bug destroyed.
|
|
27
|
+
const BEFORE_ID = 11;
|
|
28
|
+
const INF_ID = 22;
|
|
29
|
+
const AFTER_ID = 33;
|
|
30
|
+
const EXPECTED_IDS = [BEFORE_ID, INF_ID, AFTER_ID];
|
|
31
|
+
// One template, one substitution point. Derived with String.replace on a
|
|
32
|
+
// whitespace-exact literal, the controls below would silently become copies of
|
|
33
|
+
// the INF case the moment anyone reflowed the source - replace() returns its
|
|
34
|
+
// input unchanged when the token is absent - and "indexes the same as the
|
|
35
|
+
// equivalent record with a real" would degrade to expect(x).toEqual(x), which
|
|
36
|
+
// passes even with the bug reinstated.
|
|
37
|
+
const VALUE_SLOT = "<<VALUE>>";
|
|
38
|
+
const TEMPLATE = [
|
|
39
|
+
`#${BEFORE_ID}= IFCQUANTITYLENGTH('before',$,$,1.5,$);`,
|
|
40
|
+
`#${INF_ID}= IFCQUANTITYLENGTH('unbounded',$,$,${VALUE_SLOT},$);`,
|
|
41
|
+
`#${AFTER_ID}= IFCQUANTITYLENGTH('after',$,$,2.5,$);`,
|
|
42
|
+
].join("\n");
|
|
43
|
+
/**
|
|
44
|
+
* Build the fixture with a given value in the middle record's 4th attribute.
|
|
45
|
+
*
|
|
46
|
+
* @param value The value text to substitute.
|
|
47
|
+
* @return {string} The fixture source.
|
|
48
|
+
*/
|
|
49
|
+
function withValue(value) {
|
|
50
|
+
if (!TEMPLATE.includes(VALUE_SLOT)) {
|
|
51
|
+
throw new Error("fixture template lost its substitution slot");
|
|
52
|
+
}
|
|
53
|
+
return TEMPLATE.replace(VALUE_SLOT, value);
|
|
54
|
+
}
|
|
55
|
+
// Leading whitespace preserved from the real export, since it is what puts an
|
|
56
|
+
// identifier-like token where an attribute is expected.
|
|
57
|
+
const WITH_INF = withValue(" INF");
|
|
58
|
+
// The control: whatever the index looks like with an ordinary real is what the
|
|
59
|
+
// INF version has to match.
|
|
60
|
+
const WITHOUT_INF = withValue("3.5");
|
|
61
|
+
// The same export writes `-INF` for the opposite bound. Also a CONTROL, not a
|
|
62
|
+
// second case of the bug: a leading '-' is dispatched as a number, so it never
|
|
63
|
+
// reaches the inline-instance recovery and was never affected. Kept so that
|
|
64
|
+
// stays visible - the defect is specific to the bare identifier-like form, and
|
|
65
|
+
// anyone reading INF handling should not assume both directions went through
|
|
66
|
+
// it.
|
|
67
|
+
const WITH_NEGATIVE_INF = withValue(" -INF");
|
|
68
|
+
/**
|
|
69
|
+
* Parse a data block and return each top-level entry's express ID, in order.
|
|
70
|
+
*
|
|
71
|
+
* @param source The STEP text to parse.
|
|
72
|
+
* @return {number[]} Express IDs as indexed.
|
|
73
|
+
*/
|
|
74
|
+
function indexedExpressIDs(source) {
|
|
75
|
+
const input = new ParsingBuffer(new TextEncoder().encode(source));
|
|
76
|
+
const [index, result] = parser.parseDataBlock(input);
|
|
77
|
+
// INCOMPLETE is the expected result for a bare run of records with no
|
|
78
|
+
// ENDSEC; terminator - what matters here is that it is not a syntax error.
|
|
79
|
+
expect([ParseResult.COMPLETE, ParseResult.INCOMPLETE]).toContain(result);
|
|
80
|
+
return index.elements.map((element) => element.expressID);
|
|
81
|
+
}
|
|
82
|
+
describe("a bare INF attribute", () => {
|
|
83
|
+
test("does not stamp its express ID over the records before it", () => {
|
|
84
|
+
expect(indexedExpressIDs(WITH_INF)).toEqual(EXPECTED_IDS);
|
|
85
|
+
});
|
|
86
|
+
test("indexes the same as the equivalent record with a real", () => {
|
|
87
|
+
expect(indexedExpressIDs(WITH_INF))
|
|
88
|
+
.toEqual(indexedExpressIDs(WITHOUT_INF));
|
|
89
|
+
});
|
|
90
|
+
// Passes with or without the fix, by design - see WITH_NEGATIVE_INF above.
|
|
91
|
+
test("negative INF is dispatched as a number and never took this path", () => {
|
|
92
|
+
expect(indexedExpressIDs(WITH_NEGATIVE_INF)).toEqual(EXPECTED_IDS);
|
|
93
|
+
});
|
|
94
|
+
// The whole file has to remain resolvable, not just the index array: a
|
|
95
|
+
// corrupted express ID column makes getElementByExpressID hand back the
|
|
96
|
+
// wrong record, which is how this surfaced as relationship failures rather
|
|
97
|
+
// than as a parse error.
|
|
98
|
+
test("every record is still reachable by its own express ID", () => {
|
|
99
|
+
const [result, model] = parser.parseDataToModel(new ParsingBuffer(new TextEncoder().encode(WITH_INF)));
|
|
100
|
+
expect([ParseResult.COMPLETE, ParseResult.INCOMPLETE]).toContain(result);
|
|
101
|
+
expect(model).not.toBeUndefined();
|
|
102
|
+
for (const expressID of EXPECTED_IDS) {
|
|
103
|
+
const element = model?.getElementByExpressID(expressID);
|
|
104
|
+
expect(element).not.toBeUndefined();
|
|
105
|
+
expect(element?.expressID).toBe(expressID);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_parser.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,2BAA2B,CAAA;AAEjD,OAAO,aAAa,MAAM,8BAA8B,CAAA;AAcxD,OAAO,iBAAiB,EAAE,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEpE,MAAM,WAAW,kBAAkB,CAAC,UAAU;IAE5C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAA;IAE/C,cAAc,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAA;CACpD;AAED,MAAM,WAAW,oBAAoB,CAAC,UAAU,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IAEtF,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,MAAM,WAAW,cAAc,CAAC,UAAU,CAAE,SAAQ,kBAAkB,CAAC,UAAU,CAAC;IAEhF,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,SAAS,CAAC,UAAU;IAEnC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,CAAA;CAEvC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa,CAAC,UAAU;IAEvC;;;;;OAKG;IACH,YAAY,CAAE,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,GAAI,IAAI,CAAA;IAEvD;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,GAAG,CAAA;CACX;AAID;;GAEG;AAGH,oBAAY,WAAW;IAErB,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,YAAY,IAAI;IAChB,YAAY,IAAI;IAChB,YAAY,IAAI;CACjB;AAyBD,MAAM,MAAM,gBAAgB,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAA;AAC/E,MAAM,MAAM,uBAAuB,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAE,WAAW,EAAE,MAAM,KAAM,IAAI,CAAA;AAWnE,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;AAGzD;;GAEG;AACH,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAkB;IAE3C;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,gBAAgB,CAQ7C;IAED;;;;;OAKG;IACI,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB;CA0L5D;AACD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,UAAU,CAAE,SAAQ,gBAAgB;IAQtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IANnC;;;;;OAKG;gBAC0B,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAKpE;;;;;;;;;;;;;OAaG;IACI,gBAAgB,CACnB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IA+D9E;;;;;;;;;;OAUG;IACI,cAAc,CACjB,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,qBAAqB,GAAI,gBAAgB,CAAC,UAAU,CAAC;IAgBtE;;;;;;;;;;;;;;;;;OAiBG;IACI,sBAAsB,CACzB,KAAK,EAAE,aAAa,EACpB,gBAAgB,EAAE,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,EAClD,eAAe,CAAC,EAAE,CAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,KAAM,IAAI,EAChG,UAAU,CAAC,EAAE,qBAAqB,EAClC,IAAI,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,GAAI,gBAAgB,CAAC,UAAU,CAAC;IAiBpE;;;;;;;;;;;;;;;;;OAiBG;IACU,2BAA2B,CACpC,KAAK,EAAE,aAAa,EACpB,gBAAgB,EAAE,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,EAClD,eAAe,CAAC,EAAE,CAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,KAAM,IAAI,EAChG,UAAU,CAAC,EAAE,qBAAqB,EAClC,IAAI,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,EAChC,eAAe,GAAE,MAAwC,GACzD,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAwBzC;;;;;;;;;;;OAWG;IACU,mBAAmB,CAC5B,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,qBAAqB,EAClC,eAAe,GAAE,MAAwC,GACzD,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAuBzC;;;;;;;;;OASG;IACH,OAAO,CAAE,yBAAyB;
|
|
1
|
+
{"version":3,"file":"step_parser.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/step_parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -661,9 +661,38 @@ export default class StepParser extends StepHeaderParser {
|
|
|
661
661
|
input.begin();
|
|
662
662
|
const elementResult = parseInlineElement();
|
|
663
663
|
if (elementResult !== (void 0)) {
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
664
|
+
// No stamping here. This used to run
|
|
665
|
+
//
|
|
666
|
+
// for ( const element of elementResult[0].elements ) {
|
|
667
|
+
// element.expressID = expressID
|
|
668
|
+
// }
|
|
669
|
+
//
|
|
670
|
+
// and elementResult[0] is `indexResult` - syntaxError() returns
|
|
671
|
+
// it wholesale - so that wrote THIS record's express ID over
|
|
672
|
+
// every top-level entry indexed so far in the block.
|
|
673
|
+
//
|
|
674
|
+
// It cannot have been doing anything useful. Both pushEntry
|
|
675
|
+
// sites already set `expressID` at construction, so every entry
|
|
676
|
+
// arrives correct and the loop could only overwrite correct
|
|
677
|
+
// values with one wrong one. The same recovery inside the nested
|
|
678
|
+
// parseInlineElement - begin, parse, rollback, tokenws(INF) - has
|
|
679
|
+
// never had the loop and works.
|
|
680
|
+
//
|
|
681
|
+
// Note it ran BEFORE the rollback and the INF check, so it was
|
|
682
|
+
// never specific to INF: any top-level inline-instance parse
|
|
683
|
+
// failure poisoned the index the same way. And the index is not
|
|
684
|
+
// discarded on a syntax error - parseDataToModel builds the
|
|
685
|
+
// model from itemIndex.elements whatever the ParseResult, and
|
|
686
|
+
// the loaders only log and continue - so a poisoned index does
|
|
687
|
+
// reach consumers.
|
|
688
|
+
//
|
|
689
|
+
// What kept it hidden is narrower than that: no public corpus
|
|
690
|
+
// model reaches this recovery at all. A private one does, via an
|
|
691
|
+
// exporter writing `IFCQUANTITYLENGTH(...,INF,$)` for an
|
|
692
|
+
// unbounded quantity - not valid ISO 10303-21, but what the tool
|
|
693
|
+
// emits - where it cost 3,116 entities and produced 630
|
|
694
|
+
// relationship failures all naming the same record.
|
|
695
|
+
// See #412, #481, #482.
|
|
667
696
|
input.rollback();
|
|
668
697
|
if (tokenws(INF)) {
|
|
669
698
|
break;
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
// only the first segment (major) is meaningful and is the one CI carries forward.
|
|
6
6
|
// Must stay in `vN.N.N` shape: the CI stamp regex, scripts/updateVersion.mjs, and
|
|
7
7
|
// statistics.ts all match `v\d+\.\d+\.\d+`.
|
|
8
|
-
const versionString = 'Conway v1.
|
|
8
|
+
const versionString = 'Conway v1.500.1420';
|
|
9
9
|
export { versionString };
|