Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions iosMath/lib/MTMathListBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -746,15 +746,18 @@ - (MTMathAtom*) atomForCommand:(NSString*) command
} else if ([command isEqualToString:@"sqrt"]) {
// A sqrt command with one argument
MTRadical* rad = [MTRadical new];
unichar ch = [self getNextCharacter];
if (ch == '[') {
// special handling for sqrt[degree]{radicand}
rad.degree = [self buildInternal:false stopChar:']'];
rad.radicand = [self buildInternal:true];
} else {
[self unlookCharacter];
rad.radicand = [self buildInternal:true];
// Guard against a lone "\sqrt" at the end of input: only read a
// character if one is available.
if ([self hasCharacters]) {
unichar ch = [self getNextCharacter];
if (ch == '[') {
// special handling for sqrt[degree]{radicand}
rad.degree = [self buildInternal:false stopChar:']'];
} else {
[self unlookCharacter];
}
}
Comment on lines +751 to 759
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The nested conditional logic can be simplified by pulling the common rad.radicand = [self buildInternal:true]; call out of the conditional branches. This eliminates redundant code duplication and improves readability.

        if ([self hasCharacters]) {
            unichar ch = [self getNextCharacter];
            if (ch == '[') {
                // special handling for sqrt[degree]{radicand}
                rad.degree = [self buildInternal:false stopChar:']'];
            } else {
                [self unlookCharacter];
            }
        }
        rad.radicand = [self buildInternal:true];

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Pulled the common rad.radicand = [self buildInternal:true] out of all three branches into a single call after the optional degree parse. Kept a brief comment noting the lone-\sqrt guard. All 119 tests pass.

rad.radicand = [self buildInternal:true];
return rad;
} else if ([command isEqualToString:@"left"]) {
// Save the current inner while a new one gets built.
Expand Down
49 changes: 49 additions & 0 deletions iosMathTests/MTMathListBuilderTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,55 @@ - (void) testSqrt
XCTAssertEqualObjects(latex, @"\\sqrt{2}", @"%@", desc);
}

- (void) testSqrtAtEnd
{
// A lone \sqrt with no argument at the end of the input must not crash
// (it previously asserted in getNextCharacter). It should parse as a
// radical with an empty radicand, matching \sqrt{}.
NSString *str = @"\\sqrt";
MTMathList* list = [MTMathListBuilder buildFromString:str];
NSString* desc = [NSString stringWithFormat:@"Error for string:%@", str];

XCTAssertNotNil(list, @"%@", desc);
XCTAssertEqualObjects(@(list.atoms.count), @1, @"%@", desc);
MTRadical* rad = list.atoms[0];
XCTAssertEqual(rad.type, kMTMathAtomRadical, @"%@", desc);
XCTAssertEqualObjects(rad.nucleus, @"", @"%@", desc);

MTMathList *subList = rad.radicand;
XCTAssertNotNil(subList, @"%@", desc);
XCTAssertEqualObjects(@(subList.atoms.count), @0, @"%@", desc);
XCTAssertNil(rad.degree, @"%@", desc);

// convert it back to latex
NSString* latex = [MTMathListBuilder mathListToString:list];
XCTAssertEqualObjects(latex, @"\\sqrt{}", @"%@", desc);
}

- (void) testSqrtInGroup
{
// A \sqrt with no argument inside a group exercises a different path
// (empty radicand via the oneCharOnly stop-char guard) than the
// end-of-input case, and must also not crash.
NSString *str = @"{\\sqrt}";
MTMathList* list = [MTMathListBuilder buildFromString:str];
NSString* desc = [NSString stringWithFormat:@"Error for string:%@", str];

XCTAssertNotNil(list, @"%@", desc);
XCTAssertEqualObjects(@(list.atoms.count), @1, @"%@", desc);
MTRadical* rad = list.atoms[0];
XCTAssertEqual(rad.type, kMTMathAtomRadical, @"%@", desc);

MTMathList *subList = rad.radicand;
XCTAssertNotNil(subList, @"%@", desc);
XCTAssertEqualObjects(@(subList.atoms.count), @0, @"%@", desc);
XCTAssertNil(rad.degree, @"%@", desc);

// convert it back to latex
NSString* latex = [MTMathListBuilder mathListToString:list];
XCTAssertEqualObjects(latex, @"\\sqrt{}", @"%@", desc);
}

- (void) testSqrtInSqrt
{
NSString *str = @"\\sqrt\\sqrt2";
Expand Down
Loading